Shiro之与SpringMVC集成
作者:互联网
SpringMVC 环境省略
http://shiro.apache.org/download.html
pom.xml增加maven依赖
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-aspectj</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-cas</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-guice</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.6</version> </dependency>
web.xml增加shiro-filter,放在所有filter之前
<!-- Shiro Filter --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
建立首页,登录页等等相关控制器和页面
增加spring-shiro.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--Shiro主过滤器 此处的id必须和web.xml里的filter-name一样 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- Shiro的核心安全接口,这个属性是必须的 --> <property name="securityManager" ref="securityManager"></property> <!-- 未认证,要跳转的url,非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 --> <property name="loginUrl" value="/loginPage"></property> <!-- 未授权,要跳转的url --> <property name="unauthorizedUrl" value="/unauthorizedPage"></property> <property name="filterChainDefinitions"> <!-- anon:可以匿名访问 authc:必须认证登录后才能访问 --> <value> /loginPage=anon /doLogin=anon /doLogout=anon /*=authc </value> </property> </bean> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="cacheManager" ref="cacheManager"></property> <property name="authenticator" ref="authenticator"></property> <property name="realms"> <list> <ref bean="realm1"/> </list> </property> </bean> <!-- 认证策略 --> <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator"> <property name="authenticationStrategy"> <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean> </property> </bean> <!-- Realm --> <bean id="realm1" class="com.zns.realm.Realm1"> <!--密码验证方式--> <property name="credentialsMatcher"> <!--密文--> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"/> <!--加密次数--> <property name="hashIterations" value="1"></property> </bean> <!--明文--> <!-- <bean class="org.apache.shiro.authc.credential.SimpleCredentialsMatcher"> </bean> --> </property> </bean> <!-- 缓存管理 --> <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"></bean> <!-- 配置Shiro生命周期处理器 会自动的调用和Spring整合后各个组件的生命周期方法 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean> <!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),必须先配置了lifecycleBeanPostProcessor才可以使用 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"></bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"></property> </bean> </beans>
在web.xml里的contextConfigLocation的Spring核心监听器增加spring-shiro.xml文件路径
控制器核心代码如下
package com.zns.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.DisabledAccountException; import org.apache.shiro.authc.ExcessiveAttemptsException; import org.apache.shiro.authc.ExpiredCredentialsException; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.LockedAccountException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.UnauthorizedException; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class AccountController { @RequestMapping("/loginPage") public String loginPage(){ return "/login"; } @RequestMapping(value = "/doLogin") public String doLogin(HttpServletRequest request, Model model) { String msg = ""; String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("用户名: "+username+" 密码: "+password); UsernamePasswordToken token = new UsernamePasswordToken(username, password); token.setRememberMe(true); Subject subject = SecurityUtils.getSubject(); try { subject.login(token); if (subject.isAuthenticated()) { return "redirect:/"; } else { return "/login"; } } catch (IncorrectCredentialsException e) { msg = "登录密码错误. Password for account " + token.getPrincipal() + " was incorrect."; model.addAttribute("message", msg); System.out.println(msg); } catch (ExcessiveAttemptsException e) { msg = "登录失败次数过多"; model.addAttribute("message", msg); System.out.println(msg); } catch (LockedAccountException e) { msg = "帐号已被锁定. The account for username " + token.getPrincipal() + " was locked."; model.addAttribute("message", msg); System.out.println(msg); } catch (DisabledAccountException e) { msg = "帐号已被禁用. The account for username " + token.getPrincipal() + " was disabled."; model.addAttribute("message", msg); System.out.println(msg); } catch (ExpiredCredentialsException e) { msg = "帐号已过期. the account for username " + token.getPrincipal() + " was expired."; model.addAttribute("message", msg); System.out.println(msg); } catch (UnknownAccountException e) { msg = "帐号不存在. There is no user with username of " + token.getPrincipal(); model.addAttribute("message", msg); System.out.println(msg); } catch (UnauthorizedException e) { msg = "您没有得到相应的授权!" + e.getMessage(); model.addAttribute("message", msg); System.out.println(msg); } return "/login"; } @RequestMapping("/doLogout") public void doLogout(HttpServletRequest request,HttpServletResponse response) throws Exception{ Subject subject = SecurityUtils.getSubject(); if (subject != null) { try{ subject.logout(); }catch(Exception ex){ } } response.sendRedirect("loginPage"); } }
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>login</title> </head> <body> <h1>登录</h1> <form id="" action="doLogin" method="post"> <input tyep="text" name="username" placeholder="用户名" /><br><br> </label><input type="password" name="password" placeholder="密码" /><br><br> <input type="submit" value="登录" /> </form> <P><c:out value="${message}" /></P> </body> </html>
新增一个Realm1继承AuthorizingRealm类
package com.zns.realm; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.LockedAccountException; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.crypto.hash.SimpleHash; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; public class Realm1 extends AuthorizingRealm { /** * 认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //把AuthenticationToken转换成UsernamePasswordToken UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)authenticationToken; //获取username String username=usernamePasswordToken.getUsername(); //根据username从数据库查询信息(注入并调用UserService方法),此处省略 //根据获取的用户信息,决定是否抛出AuthenticationException异常,此处写死 if(username.equals("unknown")){ throw new UnknownAccountException("用户不存在!"); } if (username.equals("lock")) { throw new LockedAccountException("用户被锁定!"); } //构建并返回AuthenticationInfo,通常是SimpleAuthenticationInfo //principal:可以是username,也可以是数据表对应的用户实体类对象 //credentials:从数据库获取的密码 //realmName:当前realm对象的name Object principal=username; //Object credentials="123456"; Object credentials=new SimpleHash("MD5", "123456", "", 1); String realmName=this.getName(); SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal, credentials, realmName); return info; } /** * 授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } public static void main(String[] args) { String algorithmName="MD5"; String source="123456"; String salt=""; int hashIterations=1; Object result=new SimpleHash(algorithmName, source, salt, hashIterations); System.out.println(result); } }
运行项目测试登录认证功能.......
标签:集成,SpringMVC,msg,Shiro,import,apache,org,shiro,authc 来源: https://www.cnblogs.com/zengnansheng/p/10389583.html