shiro大致介绍,shiro-Spring整合细节,shiro基本使用,自定义方法使用shiro

shiro大致介绍

shiro是什么

shiro是apache组织下维护的一个安全框架.
1. 帮我们做认证.
2. 帮我们做权限的校验.
3. 帮我们做密码加密加盐.
4. shiro可以自定义Session.
5. shiro可以帮我们缓存用户权限信息.
6. shiro还一共了各种认证/授权的校验方式,针对项目类型可以自由选择.

shiro和Spring security比较

  1. shiro可以脱离Spring单独使用. Spring security无法脱离Spring单独使用
  2. shiro是一款很轻的安全框架,学习简单. spring security相对更重,学习成本比较高.
  3. shiro关于全县控制的粒度相对更粗. spring security对权限的控制很细
  4. spring之前的官网用的是shiro.

shiro的架构

在这里插入图片描述

shiro的入门

  1. 创建项目

  2. 导入依赖

    shiro-core-1.4.0

  3. simpleRealm,iniRealm,JdbcRealm创建分为几步,大致相同

    1. 创建Realm对象

    2. 创建SecurityManager对象

      2.1 给Security Manager对象设置创建好的Realm对象

    3. 生成Subject主题

      3.1 给SecurityUtils设置上securityManager对象

      3.2 用SecurityUtils创建subject主体

    4. 由主体发起认证请求 subject.login((“username”,“password”));

      如果用户名或密码错误shiro直接抛出异常。

      用户名错误UnKnowAccountException(账户异常)

      密码错误IncorreCredentialsException(凭据异常|密码错误)

    5. 判断是否登陆过

      subjec.isAuthentication

    6. 角色的授权认证

      subject.checkRoles

    7. 角色的权限校验

      subject.checkPremissions

simpleRealm

// 1. 创建SimpleRealm对象.
SimpleAccountRealm realm = new SimpleAccountRealm();
realm.addAccount("admin", "admin");

//创建创建SecurityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(realm);

//创建Subject主题
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();

//4. 由主体发起认证请求.
subject.login(new UsernamePasswordToken("admin", "admin"));
// 如果用户名或密码错误,shiro直接抛出异常.
// 用户名错误 -> UnknowAccountException     密码错误 -> 	IncorrectCredentialsException				                   
//判断是否验证过
if(subject.isAuthenticated()){
	System.out.println("登陆成功");
}

//角色授权
boolean lala = subject.hasRole("lala");
System.out.println(lala);

iniRealm

shiro.ini

[users]
admin=admin,超级管理员,普通用户
[roles]
超级管理员=user:select,user:insert,user:delete,user:update
普通用户=user:select,user:insert
//创建iniRealmTest对象
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");

//创建SecurityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(iniRealm);

//创建subjec主体
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();

//由主体发送请求
subject.login(new UsernamePasswordToken("admin","admin"));

//判断是否校验过
if(subject.isAuthenticated()){
    System.out.println("success");
}

//角色授权
subject.checkRoles("超级管理员","普通用户");
subject.checkPermissions("user:insert","user:delete");

jdbcRealm

//1.创建Realm
JdbcRealm jdbcRealm = new JdbcRealm();
//  1.1创建数据源
DruidDataSource ds=new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql:///shiro");
ds.setUsername("root");
ds.setPassword("123456");

//导入数据源(切记,老忘)
jdbcRealm.setDataSource(ds);
//1.2手动创建sql
jdbcRealm.setAuthenticationQuery("select password from user where username=?");
//手动开启权限校验
jdbcRealm.setPermissionsLookupEnabled(true);

//创建ScurityManager
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(jdbcRealm);

//创建subjec主体
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();

//主题提交认证请求
subject.login(new UsernamePasswordToken("admin","admin"));
if(subject.isAuthenticated()){
    System.out.println("success");
}

//角色得授权
subject.checkRoles("普通用户");

//权限的授权
subject.checkPermissions("user:select");

CustomRealm自定义

  1. 自定义认证

    //获取用户输入的用户名
    String username = (String) token.getPrincipal();
    
    //根据用户名查询用户信息(模拟数据库操作)
    User user = this.selectUserByUserName(username);
    if(user==null){
        return null;
    }
    //4. 将正确的user对象和密码封装到AuthenticationInfo对象中.
    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), "realName=DN");
    //5. 将盐设置到info对象中
    info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
    
    return info;
    

    实现密码的加密和密码的加盐.
    密码加密:
    在CustomRealm中,添加代码块,指定加密方式和加密次数.
     // 设置MD5加密1024次.
     {
         HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
         matcher.setHashAlgorithmName("MD5");
         matcher.setHashIterations(1024);
      this.setCredentialsMatcher(matcher);
     }
    
     在doGetAuthenticationInfo方法中,返回info对象之前.添加以下操作.
    	info.setCredentialsSalt(ByteSource.Util.bytes(String salt));
    
  2. 自定义授权

    //获取用户输入的用户名
    User user = (User) principals.getPrimaryPrincipal();
    String username = user.getUsername();
    
    //根据用户名查询全部角色(模拟数据库操作)
    Set<String> allRoles = this.findAllRoleByUseName(username);
    
    //根据allRoles查询全部权限
    Set<String> allPermissions = this.findAllPermissionsByUsername(allRoles);
    
    //4. 创建返回结果info,并封装角色和权限.
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(allRoles);
    info.setStringPermissions(allPermissions);
    
    return info;
    

shiro-Spring整合细节

在这里插入图片描述

  1. 创建项目
  2. 导入依赖
<!--spring-->
spring-context
spring-aspects
spring-jdbc
spring-webmvc
spring-test
<!--shiro整合spring-->
shiro-core
shiro-web
shiro-spring
<!--web-->
javax.servlet.jsp-api
javax.servlet-api
//记得添加限定<scope>provided</scope
<!--通用-->
junit
druid	
mysql-connector-java
lombok
  1. web.xml配置
<!--    处理post请求中文乱码问题-->
<filter>
	<filter-name>characterRncoding</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter
	</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>utf-8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>characterRncoding</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>


<--web.xml配置过滤器.(由当前过滤器映射全部请求,并将请求交给spring容器中的一个实例做处理)
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
	<listenerclass>org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

<!--    上下文参数-->
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>


<!--    前端处理器-->
<servlet>
	<servlet-name>springmvc</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet
	</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:springmvc.xml</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>springmvc</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>
  1. 编写shiro整合spring的配置.
在shiro-spring.xml中配置id为shiroFilter的实例

注入Ralm
<bean id="realm" class="com.qf.realm.CustomRealm"></bean>

注入SecurityMannger
<bean  id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	<property name="realm" ref="realm"/>
</bean>

<bean id="shiroFilter" 							class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
	<property name="securityManager" ref="securityManager"/>
    
    过滤器链
		<property name="filterChainDefinitions">
            <value>
                /user/logout=logout 退出登陆
                /user/*=anon		直接放行
                /**=authc			需要认证后放行
            </value>
   		 </property>
    <property name="loginUrl" value="/user/login-ui"/>
    
    
   		 logout -> 退出登录 -> subject.logout();
        anon -> 直接放行 -> return true;
        authc -> 认证后才放行 -> return subject.isAuthenticated();
</bean>

关于安全管理器

<bean id="realm" class="com.qf.realm.CustomRealm" />

<bean id="securityManager" class="DefaultWebSecurityManager">
    <property name="realm" ref="realm" />
</bean>
  1. 测试

    登录页面,需要认证访问的页面.
    login-ui,login.

    1. 跳转到一个需要认证才可以进入的页面. -> 跳到登录页面.
    2. 执行登录.
    3. 跳转到一个需要认证才可以进入的页面. -> 直接进入.
    4. 退出登录. -> 跳转登录页面.
    5. 跳转到一个需要认证才可以进入的页面. -> 跳转登录页面.

    问题1: 一定要使用listener去加载shiro-spring.xml文件.
    web.xml中加载的顺序, listener > filter > servlet
    如果采用servlet加载shiro-spring.xml会导致加载filter时,直接去spring容器中找bean的name为shiroFilter的实例,但是还没有加载servlet,导致启动报错.
    问题2: 静态资源问题.
    css,js,html,img
    静态资源会被浏览器缓存,导致在退出登录后,依然可以访问静态资源.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值