shiro篇】 三. shiro登录认证与授权案例 下

【shiro篇】 三. shiro登录认证与授权案例 上

篇幅较长可以通过右侧目录查看文章目录

shiro登录认证与授权案例

项目准备

  1. 本项目基于【shiro篇】 二. shiro登录认证与授权案例 上

4 授权-角色

4.1 在ok页面添加2个超链接

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>登录成功</h1>
    <a href="/logout">注销</a><br />
    <a href="/add">add</a>
    <a href="/delete">delete</a>

</body>
</html>

4.2 UserController添加2个对应的方法

@RequestMapping("/add")
public String add(){
    return "ok";
}
@RequestMapping("/delete")
public String delete(){
    return "ok";
}

4.3 在UserRealm的授权方法AuthorizationInfo添加功能

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo sazi = new SimpleAuthorizationInfo();

        Object username = principalCollection.getPrimaryPrincipal();
        if ("admin".equals(username.toString())){
            HashSet<String> roles = new HashSet<String>();
            roles.add("admin");
            sazi.addRoles(roles);
        }
        return sazi;
    }

4.3 在spring容器中配置roles过滤器

多个角色用逗号隔开
在这里插入图片描述

4.4 新建一个没有权限页面unauthorized.jsp

这里的login.jsp,ok.jsp,unauthorized.jsp都是在spring容器的shiroFilter中配置的

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>你没有权限</h1>
</body>
</html>

4.5 测试

使用admin2为用户名登录后,点击add会跳转到没有权限的页面
使用admin则成功调用

5. 授权-权限

5.1 在spring容器中配置权限过滤器

在这里插入图片描述

5.2 在UserRealm的授权方法doGetAuthorizationInfo添加功能

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
	SimpleAuthorizationInfo sazi = new SimpleAuthorizationInfo();

    Object username = principalCollection.getPrimaryPrincipal();
    if ("admin".equals(username.toString())){
        HashSet<String> roles = new HashSet<String>();
        roles.add("admin");
        sazi.addRoles(roles);
    } else if ("admin2".equals(username.toString())){
        HashSet<String> permissions = new HashSet<String>();
        permissions.add("user:delete");
        sazi.addStringPermissions(permissions);
    }
    return sazi;
}

5.3 测试

使用admin为用户名登录的话 可以调用add,调用delete会跳转到没有权限页面。
使用admin2为用户名登录的话 可以调用delete,调用add会跳转到没有权限页面。

6. 授权方式

6.1 注解

6.1.1 在controller方法上加注解

@RequiresPermissions(“user:add”)
@RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR):表示当前 Subject 需要权限 user:a 或 user:b

@RequiresRoles(“admin”)
@RequiresRoles(value={“admin”,“user”}, logical= Logical.AND):表示当前 Subject 需要角色 admin 和user

6.1.2 配置springmvc.xml

如果要使用注解使用,首先要在配置文件中开启注解(SpringMVC配置文件中)
<!-- 启动shiro注解 -->   
<aop:config proxy-target-class="true"></aop:config>

<bean 	class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
	<property name="securityManager" ref="securityManager" />
</bean>

6.1.3 springmvc.xml配置全局异常处理

用注解如果没有权限不会自动跳到自己配的页面,会报错。

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 默认的错误视图页面 -->
    <property name="defaultErrorView" value="error" />
    <!-- 错误视图页面可以通过${ex}获取异常信息 -->
    <property name="exceptionAttribute" value="ex" />
    <property name="exceptionMappings">
        <props>
            <prop key="org.apache.shiro.authz.AuthorizationException">
                unauthorized
            </prop>
        </props>
    </property>
</bean>

6.2 jsp标签

6.2.1 导标签库

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

标签

  1. 游客 : guest
    <shiro:guest>  
    欢迎游客访问,<a href="/login.jsp">登录</a>  
    </shiro:guest>
    
  2. 用户已经认证并且选择了记住我 : user
    <shiro:user>  
    欢迎[<shiro:principal/>]登录,<a href="/logout">注销</a>  
    </shiro:user>
    
  3. 用户已经认证没有选择了记住我 : authenticated
    <shiro:authenticated>  
        用户[<shiro:principal/>]已身份验证通过  
    </shiro:authenticated>   
    
  4. 显示用户信息 : principal
    <shiro: principal/>
    
  5. 当前Subject有角色将显示body体内容 : hasRole
    <shiro:hasRole name="admin">  
        用户[<shiro:principal/>]拥有角色admin<br/>  
    </shiro:hasRole> 
    
  6. hasAnyRoles
    <shiro:hasAnyRoles name="admin,user">  
        用户[<shiro:principal/>]拥有角色admin或user<br/>  
    </shiro:hasAnyRoles>   
    
  7. 当前Subject没有角色将显示body体内容 : lacksRole
    <shiro:lacksRole name="abc">  
        用户[<shiro:principal/>]没有角色abc<br/>  
    </shiro:lacksRole>  
    
  8. 如果当前Subject有权限将显示body体内容 : hasPermission
    <shiro:hasPermission name="user:create">  
        用户[<shiro:principal/>]拥有权限user:create<br/>  
    </shiro:hasPermission>   
    
  9. 如果当前Subject没有权限将显示body体内容 : lacksPermission标签
    <shiro:lacksPermission name="org:create">  
        用户[<shiro:principal/>]没有权限org:create<br/>  
    </shiro:lacksPermission>   
    

7 记住我

7.1 修改登录页面

新增记住我选项

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>登录页面</h1>

<form action="/login">
    username:<input type="text" name="username"><br />
    password:<input type="text" name="password"><br />
    rememberMe:<input type="checkbox" name="rememberMe"><br />
    <input type="submit" value="登录">
</form>

</body>
</html>

7.2 修改控制器login方法

@RequestMapping("/login")
    public String login(String username, String password, String rememberMe){
        // 1. 获取当前用户
        Subject currentUser = SecurityUtils.getSubject();
        // *2. 判断是否登录,没有登陆返回false
        if (!currentUser.isAuthenticated()) {
            // 3。 封装用户名和密码
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            try {
                // 判断是否记住我
                if("on".equals(rememberMe)){
                    token.setRememberMe(true);
                }

                // 4. 登录
                currentUser.login(token);
            } catch (AuthenticationException ae) { // 6.3.4 其他的认证异常
                System.out.println("认证失败。。。。");
                return "login";
            }
        }
        return "ok";
    }

7.3 修改applicationContext配置文件

加密记住我存在cookies中的数据

<!-- 会话Cookie模板 -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <constructor-arg value="sid" />
    <!--设置js是否可以访问cookie,true不能访问 -->
    <property name="httpOnly" value="true" />
    <!-- 保存时长30天,以秒为单位 -->
    <property name="maxAge" value="2592000" />
</bean>

<!-- rememberMe管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
    <!-- ipherKey是加密rememberMe Cookie的密钥;默认AES算法 -->
    <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
    <!-- 引入上面定义的cookie模板 -->
    <property name="cookie" ref="rememberMeCookie" />
</bean>

在这里插入图片描述

7.4 修改过滤器

在这里插入图片描述

7.5 测试

8 总结

8.1 登录认证

  1. realm
  2. 过滤器

8.2 控制权限

  1. 过滤器:没有权限会跳转到自己配置的页面
  2. 注解和标签:没有权限会抛异常

8.3 加密

  1. 盐值加密解决加密后密码一致问题
发布了56 篇原创文章 · 获赞 11 · 访问量 4079

猜你喜欢

转载自blog.csdn.net/TheNew_One/article/details/104111710