使用FormAuthenticationFilter过虑器实现 ,原理如下:
将用户没有认证时,请求loginurl进行认证,用户身份和用户密码提交数据到loginurl
FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的)
FormAuthenticationFilter调用realm传入一个token(username和password)
realm认证时根据username查询用户信息(在Activeuser中存储,包括 userid、usercode、username、menus)。
如果查询不到,realm返回null,FormAuthenticationFilter向request域中填充一个参数(记录了异常信息)
2 登陆页面
由于FormAuthenticationFilter的用户身份和密码的input的默认值(username和password),修改页面的账号和密码 的input的名称为username和password
3.登陆代码实现
pom.xml
4.0.0
com.me
shiro-web
0.0.1-SNAPSHOT
war
junit
junit
3.8.1
test
javax.servlet
javax.servlet-api
3.1.0
javax.servlet.jsp
javax.servlet.jsp-api
2.3.1
javax.servlet
jstl
1.2
org.springframework
spring-core
4.1.7.RELEASE
org.springframework
spring-beans
4.1.7.RELEASE
org.springframework
spring-tx
4.1.7.RELEASE
org.springframework
spring-context
4.1.7.RELEASE
org.springframework
spring-context-support
4.1.7.RELEASE
org.springframework
spring-web
4.1.7.RELEASE
org.springframework
spring-webmvc
4.1.7.RELEASE
org.springframework
spring-aop
4.1.7.RELEASE
org.springframework
spring-aspects
4.1.7.RELEASE
org.springframework
spring-jdbc
4.1.7.RELEASE
org.mybatis
mybatis-spring
1.2.3
log4j
log4j
1.2.17
org.mybatis
mybatis
3.3.0
mysql
mysql-connector-java
5.1.38
org.apache.shiro
shiro-core
1.2.4
org.slf4j
slf4j-log4j12
1.7.12
org.apache.shiro
shiro-web
1.2.4
org.apache.shiro
shiro-spring
1.2.4
shiro-web
index.jsp
contextConfigLocation
classpath:spring/applicationContext-*.xml
org.springframework.web.context.ContextLoaderListener
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
targetFilterLifecycle
true
targetBeanName
shiroFilter
shiroFilter
/*
springMVC
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring/spring-mvc.xml
1
true
springMVC
*.do
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
<%
response.sendRedirect("first.do");
%>
login.jsp
login.jsp<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here
package cn.me.ssm.controller;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.me.ssm.exception.CustomException;
@Controller
public class LoginController {
//登陆提交地址,和applicationContext-shiro.xml中配置的loginurl一致
@RequestMapping("/login")
public String login(HttpServletRequest request) throws Exception {
// 如果登录失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
// 根据shiro返回的异常类路径判断,抛出指定异常信息
String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
if (exceptionClassName != null) {
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
request.setAttribute("errorMsg", "用户名不存在");
} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
request.setAttribute("errorMsg", "用户名/密码不正确");
}else {
throw new Exception();// 最终在异常处理器生成未知错误
}
}
// 此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
// 登陆失败还到login页面
request.setAttribute("username", request.getParameter("username"));
return "login";
}
}
package cn.me.ssm.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class FirstAction {
//系统首页
@RequestMapping("/first")
public String first(Model model)throws Exception{
return "/first";
}
//欢迎页面
@RequestMapping("/welcome")
public String welcome(Model model)throws Exception{
return "/welcome";
}
}
/images/** = anon
/js/** = anon
/styles/** = anon
/validatecode.jsp = anon
/logout.action = logout
/**=authc
退出
使用LogoutFilter
不用我们去实现退出,只要去访问一个退出的url(该 url是可以不存在),由LogoutFilter拦截住,清除session。
在applicationContext-shiro.xml配置的中添加退出url如:/logout.action = logout
/logout.action = logout
授权过滤器测试
使用PermissionsAuthorizationFilter
在applicationContext-shiro.xml中配置url所对应的权限。
测试流程:
1、在applicationContext-shiro.xml中配置filter规则
/items/queryItems.action = perms[item:query]
2、用户在认证通过后,请求/items/queryItems.action
3、被PermissionsAuthorizationFilter拦截,发现需要“item:query”权限
4、PermissionsAuthorizationFilter调用realm中的doGetAuthorizationInfo获取数据库中正确的权限
5、PermissionsAuthorizationFilter对item:query 和从realm中获取权限进行对比,如果“item:query”在realm返回的权限列表中,授权通过。
创建refuse.jsp
如果授权失败,跳转到refuse.jsp,需要在spring容器中配置:
shiro的过虑器
过滤器简称 对应的java类
anon org.apache.shiro.web.filter.authc.AnonymousFilter
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port org.apache.shiro.web.filter.authz.PortFilter
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl org.apache.shiro.web.filter.authz.SslFilter
user org.apache.shiro.web.filter.authc.UserFilter
logout org.apache.shiro.web.filter.authc.LogoutFilter
anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,没有参数
perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
user:例如/admins/user/**=user没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查