shiro学习笔记2——组件之身份验证

来源:互联网 发布:阿里云计算大会 编辑:程序博客网 时间:2024/06/03 05:20

在 shiro 中,用户需要提供principals (身份)和credentials(证明)给shiro,从而应用能
验证用户身份:
principals:身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。
一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。
credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。
最常见principals和credentials组合就是用户名/密码了。

身份验证的步骤:
1、收集用户身份/凭证,即如用户名/密码;
2、调用Subject.login 进行登录,如果失败将得到相应的AuthenticationException 异常,根
据异常提示用户错误信息;否则登录成功;
3、最后调用Subject.logout进行退出操作。
如上测试的几个问题:
1、用户名/密码硬编码在ini配置文件,以后需要改成如数据库存储,且密码需要加密存储;
2、用户身份Token 可能不仅仅是用户名/密码,也可能还有其他的,如登录时允许用户名/
邮箱/手机号同时登录。

通过shiro 自带的formAuthenticationFilter 拦截器进行登录,登录失败的话
会把错误存到shiroLoginFailure 属性中,在该控制器中获取后来显示相应的错误信息。
需要在spring-config-shiro.xml中配置

<!-- 基于Form表单的身份验证过滤器 -->    <bean id="formAuthenticationFilter"          class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">        <property name="usernameParam" value="username"/>        <property name="passwordParam" value="password"/>        <property name="rememberMeParam" value="rememberMe"/>        <property name="loginUrl" value="/login"/>    </bean>    <!-- Shiro的Web过滤器 -->    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">        <property name="securityManager" ref="securityManager"/>        <property name="loginUrl" value="/login"/>        <property name="filters">            <util:map>                <entry key="authc" value-ref="formAuthenticationFilter"/>                <entry key="sysUser" value-ref="sysUserFilter"/>            </util:map>        </property>        <property name="filterChainDefinitions">            <value>                /login = authc                /logout = logout                /authenticated = authc                /** = user,sysUser            </value>        </property>    </bean>

通过自定义的sysUserFilter用于根据当前登录用户身份获取User信息放入request;然后就可以通过request获取User。
需要在
spring-config-shiro.
<bean id="sysUserFilter" class="com.routon.sys.web.shiro.filter.SysUserFilter"/>
密解密

Shiro 提供了CredentialsMatcher 的散列实现HashedCredentialsMatcher,它只用于密码验证,且可以提供自己的盐,而不是随机生成盐,且生成密码散列值的算法需要自己写,因为能提供自己的盐。
生成密码散列值
使用MD5算法,“密码+盐(自定义的盐)”的方式生成散列值

String algorithmName = "md5";String username = "zhang";String password = "123456";String salt = 8d78869f470951332959580424d4bf4f;int hashIterations = 2;SimpleHash hash = new SimpleHash(algorithmName, password, salt, hashIterations);

写用户模块时,需要在新增用户/重置密码时使用如上算法保存密码,将生成的密码及
salt存入数据库
生成的密码交给realm

       //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(                user.getUsername(), //用户名                user.getPassword(), //密码                ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt                getName()  //realm name        );

具体参看:spring-config-shiro.xml

 <!-- 凭证匹配器 -->    <bean id="credentialsMatcher" class="com.routon.sys.credentials.RetryLimitHashedCredentialsMatcher">        <constructor-arg ref="cacheManager"/>        <property name="hashAlgorithmName" value="md5"/>        <!--散列迭代次数-->        <property name="hashIterations" value="2"/>        <!--表示是否存储散列后的密码为16 进制,默认是base64  -->        <property name="storedCredentialsHexEncoded" value="true"/>    </bean>    <!-- Realm实现 -->    <bean id="userRealm" class="com.routon.sys.realm.UserRealm">        <property name="credentialsMatcher" ref="credentialsMatcher"/>        <property name="cachingEnabled" value="false"/>        <!--<property name="authenticationCachingEnabled" value="true"/>-->        <!--<property name="authenticationCacheName" value="authenticationCache"/>-->        <!--<property name="authorizationCachingEnabled" value="true"/>-->        <!--<property name="authorizationCacheName" value="authorizationCache"/>-->    </bean>

访问控制
在系统中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作
等)。
通过在执行的方法上放置相应的注解完成:

@RequiresPermissions("sys:role:view")@RequestMapping(method = RequestMethod.GET)public String list(Model model) {        model.addAttribute("roleList", roleService.findAll());        return "role/list";}

在JSP页面通过相应的标签完成:

<shiro:hasPermission name="sys:role:view"><!— 有权限—></shiro:hasPermission>
原创粉丝点击