Shiro安全框架案例

基于Shiro的用户认证(不包含授权)

Spring整合Shiro

shiro原理

1.1   搭建环境

1.1.1      web模块 pom.xml

<dependency>
    <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency> <!--shiro核心包--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency>

1.1.2  Web.xml配置

<!-- Shiro Security filter  filter-name这个名字的值将来还会在spring中用到,本段代码原样粘贴,注意该过滤器是代理过滤器,它什么都不干,可以通过再Spring整合中配置相应的过滤器权限拦截器进行相应的过滤器拦截-->
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param>
<!--如果设置"targetFilterLifecycle"为true,则spring来管理Filter.init()和Filter.destroy();若为false,则这两个方法失效--> <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>

1.1.3  Spring整合shiro  applicationContext-shiro.xml

 <description>Shiro与Spring整合</description> <!--安全管理器--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!-- 引用自定义的realm --> <property name="realm" ref="authRealm"/> </bean> <!-- 自定义Realm域的编写 --> <bean id="authRealm" class="此处为自定义Realm域的全限定类名"> <!-- 注入自定义Realm域的密码比较器 --> <property name="credentialsMatcher" ref="customerCredentialsMatcher" ></property> </bean> <!-- 密码比较器:密码加密和比较 --> <bean id="customerCredentialsMatcher" class="自定义的证书匹配器所在的全限定类名"/> <!-- filter-name这个名字的值来自于web.xml中filter的名字 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--登录页面 --> <property name="loginUrl" value="/login.jsp"></property> <!-- 登录失败后 跳转到未经授权的页面 --> <property name="unauthorizedUrl" value="/unauthorized.jsp"></property>  <!--过滤器链定义,此处为访问路径设置过滤器链--> <property name="filterChainDefinitions"> <!-- /**代表下面的多级目录也过滤,等号后面的单词就是过滤器 --> <value>

<!--如果该路径的用户不包含“模块管理”权限就禁止访问--> <!-- /system/module/list.do = perms["模块管理"] userLogin.do /userLogin* = anon mylogiin.jsp /mylogin* = anon --> /index.jsp* = anon /login.jsp* = anon /login* = anon /logout* = anon /css/** = anon /img/** = anon /plugins/** = anon /make/** = anon <!-- --> /** = authc /*.* = authc </value> </property> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 生成代理,通过代理进行控制 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true"/> </bean> <!-- 安全管理器 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <aop:aspectj-autoproxy proxy-target-class="true"/>

2.1 自定义realm

/**
 * 自定义reamlm*/
public class AuthRealm extends AuthorizingRealm { @Autowired private UserService userService; @Autowired private ModuleService moduleService; /** * 授权管理:授权 */ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } /** * 身份认证 * 用于验证输入的用户名密码给,登录 */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //1.获取到用户界面输入的用户名和密码 UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken; //2.获取用户出入的用户名和密码  String username = upToken.getUsername(); String password = new String(upToken.getPassword()); //3.根据用户名查询用户对象  User user = userService.findByUsername(username); if(user != null) { //第一个参数:安全数据(user对象) //第二个参数:密码(数据库密码) //第三个参数:当前调用realm域的名称(类名即可) SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName()); return info; } return null; //subject.login()方法的时候会抛出异常  } }
AuthorizingRealm抽象类中被重写的方法来源

2.2 自定义密码比较 

在spring与shiro的整合文件中已经将该类交给realm域中,所以直接重写方法doCredentialsMatch即可

/**
 * 密码比较器
 */
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher { /** * 用户密码比较 * 1.对用户输入的密码进行加密 * 2.比较用户输入的密码和数据库密码是否一致 * @param token 用户界面输入的邮箱和密码 * @param info 安全数据:用户对象user * * 111111 + 固定值(加盐) = xxxxxx */ public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { //1.获取用户输入的密码 UsernamePasswordToken upToken = (UsernamePasswordToken) token; String loginPassword = new String(upToken.getPassword()); String email = upToken.getUsername(); //2.对登录密码进行加密 //加密:使用MD5加密 String md5Paasword = Encrypt.md5(loginPassword, email);//密码,盐 //info.getPrincipals();//获取安全数据,用户对象 //获取数据库密码 String dbPassword = (String)info.getCredentials(); //true:登录成功,false:抛出异常 return md5Paasword.equals(dbPassword); } }

 2.3 用户登录url映射

//用户登录
@RequestMapping("/login")
public String login(String username,String password) {

    //1、通过shiro框架提供的SecurityUtils工具类获取Subject Subject subject = SecurityUtils.getSubject(); //2、构造用户名密码的安全对象upToken UsernamePasswordToken upToken = new UsernamePasswordToken(username,password); //3、通过Subject的login()方法将安全对象交给shiro的安全管理器SecurityManager  subject.login(upToken); //4、通过shiro获取用户对象主体,保存到session User user = (User) subject.getPrincipal(); //获取完全对象 session.setAttribute("user",user); //5、查询菜单数据 List<Module> moduleList = moduleService.findModuleByUserid(user.getId()); session.setAttribute("modules",moduleList); return "home/main"; }

 shiro学习推荐阅读》》》》》

 》》》shiro的权限管理的注解开发只需要一个注解代码

 /**
     *  RequiresPermissions:
     *      value : 权限名称(标识)
     *  如果具备此权限:进入方法
     *  不具备此权限:抛出异常
     */
    @RequiresPermissions("模块管理")
    @RequestMapping(value = "/list",name = "查询所有") public String list(@RequestParam(defaultValue = "1")int page,@RequestParam(defaultValue = "3")int size){ PageInfo info = moduleService.findAll(page,size); request.setAttribute("page",info); return "system/module/module-list"; }

2.4   页面标签展示

通过shiro标签控制页面按钮和菜单的显示

2.4.1      引入标签库

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

2.4.2      控制显示

<shiro:hasPermission name="删除部门">
    <button type="button" class="btn btn-default" title="删除" onclick='deleteById()'><i class="fa fa-trash-o"></i> 删除</button> </shiro:hasPermission>

2.4 用户退出

//退出
    @RequestMapping(value = "/logout",name="用户登出")
    public String logout(){
        SecurityUtils.getSubject().logout();   //登出 return "forward:login.jsp"; }

shiro自动管理session,此处会将session中的用户信息清除。

点击查看SpringBoot整合Shiro

猜你喜欢

转载自www.cnblogs.com/kitor/p/11281629.html