Shiro学习认证和授权

Shiro学习笔记

认证

思路

  1. 获取当前的Subject,调用SecurityUtils.getSubject()方法;
  2. 判断当前用户是否被认证,即是否已经登陆,调用Subject的isAuthenticated()方法进行判断;
  3. 若没有认证,则把用户名和密码封装成UsernamePasswordToken对象;
    • 创建表单页面
    • 把请求提交到SpringMVC的Handler;
    • 获取用户名和密码
  4. 执行登陆:调用Subject的login()方法;
  5. 继承AuthorizingRealm类,重写认证doGetAuthenticationInfo方法
    1. 从UsernamePasswordToken中取出前端传入的用户名和密码;
    2. 将从数据中查出的用户名和密码信息封装成AuthenticationInfo对象返回(一般为Simple)
  6. 由shiro中的credentialsMatcher自动完成密码的比对;
/**  
 * 认证方法  
 * @param authenticationToken  
 * @return  
 * @throws AuthenticationException  
 */  
@Override  
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {  
    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;  
    String username = token.getUsername();  
  
    //根据用户名从数据库查询出用户名和密码  
  
    //如果用户不存在,则给出提示  
  
    //如果用户存在,根据用户的信息, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为: SimpleAuthenticationInfo  
    //认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.  
    Object principal = username;  
    //密码  
    Object credentials = null;  
  
    //realName:当前realm的name,调用父类的getName()获取  
    String realmName = getName();  
  
    //shiro会把返回的SimpleAuthenticationInfo对象和UsernamePasswordToken中的对象进行比对  
    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName);  
    return info;  
}

多Realm认证

配置

1、配置ModularRealmAuthenticator对象;并设置认证策略;
2、SecurityManager中有authenticator属性,将ModularRealmAuthenticator对象设置进去;
3、SecurityManager中有realms属性,将多个realm传进去即可;

1. 配置 SecurityManager!-->  
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
    <property name="authenticator" ref="authenticator"></property>  
  
    <property name="realms">  
        <list>  
            <ref bean="jdbcRealm"/>  
            <ref bean="secondRealm"/>  
        </list>  
    </property>  
  
	 <property name="rememberMeManager.cookie.maxAge" value="10"></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>

认证策略

认证执行流程分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

授权

授权思路

1、继承AuthorizingRealm类,重写doGetAuthorizationInfo方法,在其中实现授权的逻辑;
2、在controller中的方法上使用@RequiresPermissions注解表明需要的权限;

  1. 在controller上使用注解;
  2. 在代码中通过hasRole()、hasPermitted()等方法进行判断,
    3、请求controller中的方法时,如果方法上有权限注解,则会走重写doGetAuthorizationInfo方法发的授权逻辑,判断用户是否具有权限

ShiroFilter中可以通过下面的方式:配置哪些页面需要受保护. ,以及访问这些页面需要的权限。

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
    <property name="securityManager" ref="securityManager"/>  
    <property name="loginUrl" value="/login.jsp"/>  
    <property name="successUrl" value="/list.jsp"/>  
    <property name="unauthorizedUrl" value="/unauthorized.jsp"/>  
   
    <!-- 配置哪些页面需要受保护.  以及访问这些页面需要的权限.  
       1). anon 可以被匿名访问  
       2). authc 必须认证(即登录)后才可能访问的页面.  
       3). logout 登出.  
       4). roles 角色过滤器  
    -->  
    <property name="filterChainDefinitions">  
        <value>  
            /index.jsp = anon  
            /login.jsp = anon  
            /shiro/login = anon  
            /shiro/logout = logout  
  
            /user.jsp = roles[user]  
            /admin.jsp = roles[admin]  
  
            # everything else requires authentication:  
            /** = authc  
        </value>  
    </property>  
</bean>

但是这种方式是有缺陷的,一般我们会从数据库中读取权限,然后进行设置,所以可以对上面的配置方式进行改造,通过工厂方法创建bean

public class FilterChainDefinitionMapBuilder {

	public LinkedHashMap<String, String> buildFilterChainDefinitionMap(){
		LinkedHashMap<String, String> map = new LinkedHashMap<>();
		map.put("index.jsp", "anon");
		map.put("/login.jsp", "anon");
		map.put("/shiro/login", "anon");
		map.put("/shiro/logout", "logout");
		map.put("/user.jsp", "authc,roles[user]");
		map.put("/admin.jsp", "authc,roles[admin]");
		map.put("/list.jsp", "user");
		
		map.put("/**", "authc");
		
		return map;
	}
}
<!--配置 ShiroFilter,id 必须和 web.xml 文件中配置的 DelegatingFilterProxy<filter-name> 一致. 若不一致, 则会抛出: NoSuchBeanDefinitionException. 因为 Shiro 会来 IOC 容器中查找和 <filter-name> 名字对应的 filter bean.-->  
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
    <property name="securityManager" ref="securityManager"/>  
    <property name="loginUrl" value="/login.jsp"/>  
    <property name="successUrl" value="/list.jsp"/>  
    <property name="unauthorizedUrl" value="/unauthorized.jsp"/>  
      
    <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>  
</bean>  
  
<!-- 配置一个 bean, 该 bean 实际上是一个 Map. 通过实例工厂方法的方式 -->  
    <bean id="filterChainDefinitionMap"  
          factory-bean="filterChainDefinitionMapBuilder" factory-method="buildFilterChainDefinitionMap"></bean>  
  
    <bean id="filterChainDefinitionMapBuilder"  
          class="com.example.factory.FilterChainDefinitionMapBuilder"></bean>

常用权限注解:
在这里插入图片描述

参考

  1. Shiro视频
  2. 若依开源项目
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值