您的位置:首页 > 其它

SSM集成Shiro安全框架(三)

2018-10-23 18:33 106 查看

七、实现or关系的角色过滤

1.RoleOrFilterAuthorizationFilter.java

[code]package com.yan.shiro.common;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

public class RoleOrFilterAuthorizationFilter extends AuthorizationFilter{

@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;

if (rolesArray == null || rolesArray.length == 0)
{
return true;
}
for(int i=0;i<rolesArray.length;i++)
{
if(subject.hasRole(rolesArray[i]))
{
return true;
}
}
return false;
}

}

2.applicationContext-shiro.xml

[code]	<bean id="shiroFilter"
class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 调用我们配置的权限管理器 -->
<property name="securityManager" ref="securityManager" />
<!-- 配置我们的登录请求地址 -->
<property name="loginUrl" value="/login.jsp" />
<!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址  -->
<property name="successUrl" value="/index.jsp" />
<!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 -->
<property name="unauthorizedUrl" value="/unauthorized.jsp" />
<property name="filters">
<util:map>
<!-- 自定义roleOrFilter -->
<entry key="roleOrFilter" value-ref="roleOrFilter" />
<entry key="logout" value-ref="logoutFilter" />
</util:map>
</property>
[code]/index.jsp = roleOrFilter["admin","productManager"] <!--只需具有其中一个权限就可以,但需要自定义filter -->
[code]<!--自定义的filter -->
<bean id="roleOrFilter" class="com.yan.shiro.common.RoleOrFilterAuthorizationFilter"></bean>

八、shiro集成kaptcha验证码

1.pom.xml

[code]		<!-- Shiro 集成验证码 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>

2.spring-mvc.xml配置文件

[code]    <!-- 配置kaptcha验证码 -->
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg type="java.util.Properties">
<props>
<prop key="kaptcha.image.width">100</prop>
<prop key="kaptcha.image.height">50</prop>
<prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.NoNoise</prop>
<prop key="kaptcha.textproducer.char.string">0123456789abcdefghijklmnopqrstuvwxyz</prop>
<prop key="kaptcha.textproducer.char.length">4</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>

3.applicationContext-shiro.xml

[code]<!-- 配置我们的登录请求地址 -->
<property name="loginUrl" value="/login.jsp" />
[code]!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
<entry key="authc" value-ref="myAuthenFilter" />
[code]/login.jsp=authc
[code]<bean id="myAuthenFilter" class="com.yan.shiro.common.CaptchaFormAuthenticationFilter"/>

4.CaptchaFormAuthenticationFilter.java

[code]package com.yan.shiro.common;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yan.shiro.exception.IncorrectCaptchaException;

public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter {
private static final Logger LOG = LoggerFactory.getLogger(CaptchaFormAuthenticationFilter.class);

private static void sysout() {
System.out.println("CaptchaFormAuthenticationFilter");
}

public CaptchaFormAuthenticationFilter() {
}

@Override
/**
* 登录验证
*/
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
System.out.println("executeLogin");
CaptchaUsernamePasswordToken token = createToken(request, response);
try {
/* 图形验证码验证 */
doCaptchaValidate((HttpServletRequest) request, token);
Subject subject = getSubject(request, response);
subject.login(token);// 正常验证
LOG.info(token.getUsername() + "登录成功");
return onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException e) {
LOG.info(token.getUsername() + "登录失败--" + e);
return onLoginFailure(token, e, request, response);
}
}

// 验证码校验
protected void doCaptchaValidate(HttpServletRequest request, CaptchaUsernamePasswordToken token) {
System.out.println("doCaptchaValidate");
// session中的图形码字符串
String captcha = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
// 比对
if (captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())) {
throw new IncorrectCaptchaException("验证码错误!");
}
}

@Override
protected CaptchaUsernamePasswordToken createToken(ServletRequest request, ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
String captcha = getCaptcha(request);
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
return new CaptchaUsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha);
}

public static final String DEFAULT_CAPTCHA_PARAM = "captcha";

private String captchaParam = DEFAULT_CAPTCHA_PARAM;

public String getCaptchaParam() {
return captchaParam;
}

public void setCaptchaParam(String captchaParam) {
this.captchaParam = captchaParam;
}

protected String getCaptcha(ServletRequest request) {
return WebUtils.getCleanParam(request, getCaptchaParam());
}

// 保存异常对象到request
@Override
protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
request.setAttribute(getFailureKeyAttribute(), ae);
}
}

5.CaptchaUsernamePasswordToken.java

[code]package com.yan.shiro.common;

import org.apache.shiro.authc.UsernamePasswordToken;

public class CaptchaUsernamePasswordToken extends UsernamePasswordToken{
//验证码字符串
private String captcha;

public CaptchaUsernamePasswordToken(String username, char[] password,
boolean rememberMe, String host, String captcha) {
super(username, password, rememberMe, host);
this.captcha = captcha;
}

public String getCaptcha() {
return captcha;
}

public void setCaptcha(String captcha) {
this.captcha = captcha;
}
}

6.login.jsp

[code]<%@page import="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"%>
<%@page import="com.yan.shiro.exception.IncorrectCaptchaException"%>
<%@page import="org.apache.shiro.authc.AuthenticationException"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
.error {
color: red;
}
</style>
<script type="text/javascript">
function refreshCaptcha(){
document.getElementById("img_captcha").src="http://localhost:8081/ShiroDemo/kaptcha?t=" + Math.random();
}
</script>
</head>
<body>

<%
Object obj = request
.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
String msg = "";
if (obj != null) {
if (obj instanceof IncorrectCaptchaException)
msg = "验证码错误!";
else
msg = "账号或密码错误!";
}

out.println("<div class='error'>" + msg + "</div>");
%>

<form action="login.jsp" method="post">
<input type="hidden" name="rememberMe" value="0" /> <br />
<table>

<tr>
<td>用户帐号:</td>
<td><input type="text" name="username" id="username" value="" /></td>
</tr>
<tr>
<td>登录密码:</td>
<td><input type="password" name="password" id="password"
value="" /></td>
</tr>
<tr>
<td>验证码:</td>
<td><input type="text" name="captcha" /></td>
</tr>
<tr>
<td> </td>
<td><img alt="验证码" src="http://localhost:8081/ShiroDemo/kaptcha" title="点击更换"
id="img_captcha" onclick="javascript:refreshCaptcha();">(看不清<a href="javascript:void(0)" onclick="javascript:refreshCaptcha()">换一张</a>)</td>
</tr>
<tr>
<td colspan="2"><input value="登录" type="submit"></td>
</tr>
</table>

</form>
</body>
</html>

7.Controller.java

[code]    @Autowired
private Producer captchaProducer;

@RequestMapping(value = "/kaptcha")
public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
//生成验证码
String capText = captchaProducer.createText();
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
//向客户端写出
BufferedImage bi = captchaProducer.createImage(capText);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
}
/**
* 获取验证码
*
* @author atd681
* @since 2018年8月13日
*/
@RequestMapping("/kaptcha/get")
@ResponseBody
public String getKaptcha(HttpSession session) {
// Kaptcha生成验证后保存SESSION中的KEY为KAPTCHA_SESSION_KEY
return (String) session.getAttribute("KAPTCHA_SESSION_KEY");
}

九、demo下载

GitHub:https://github.com/709248556/shiroDemo

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: