shiro,登录处理

 1原理

使用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
		


	

web.xml



	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
		/*
	
	

	


index.jsp

<%
response.sendRedirect("first.do");
%>

login.jsp

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>  
  
  
  
  
Insert title here  
  
  
userName:
password:
${errorMsg }


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";
		
	}
}	

application-shiro.xml




	
	

	
	
		
	

	
	
		
		
		
		
		
		
		
		
		
		
			
			    
				
				/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容器中配置:


	
		
		
		
		
		
		
		
		



授权问题总结
1、在applicationContext-shiro.xml中配置过虑器链接,需要将全部的url和权限对应起来进行配置,比较发麻不方便使用。

2、每次授权都需要调用realm查询数据库,对于系统性能有很大影响,可以通过shiro缓存来解决。




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没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查



你可能感兴趣的:(shiro)