shiro介绍

什么是shiro

Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。

官方地址:https://shiro.apache.org/

为什么要学shiro

既然shiro将安全认证相关的功能抽取出来组成一个框架,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。

shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro。

java领域中spring security(原名Acegi)也是一个开源的权限管理框架,但是spring security依赖spring运行,而shiro就相对独立,最主要是因为shiro使用简单、灵活,所以现在越来越多的用户选择shiro。

Shiro基本流程

Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;所有Subject 都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者; SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager 交互;且它管理着所有Subject;可以看出它是Shiro 的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器; Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

Subject

Subject即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。 Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权

SecurityManager

SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。 SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。

Authenticator

Authenticator即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。

Authorizer

Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。

realm

Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。

注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。

sessionManager

sessionManager即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。

SessionDAO

SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库。

CacheManager

CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能。

Cryptography

Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

shiro认证

入门程序

官方参考:https://shiro.apache.org/tutorial.html

创建java工程

加入Jar包

​ 与其它java开源框架类似,将shiro的jar包加入项目就可以使用shiro提供的功能了。shiro-core是核心包必须选用,还提供了与web整合的shiro-web、与spring整合的shiro-spring、与任务调度quartz整合的shiro-quartz等,下边是shiro各jar包的maven坐标。

    <properties><shiro-version>1.4.0</shiro-version></properties><!--**********shiro**********--><!--shiro核心--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro-version}</version></dependency><!--shiro与web集成--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro-version}</version></dependency><!--shiro与spring集成--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro-version}</version></dependency>

log4j.properties日志配置文件

log4j.rootLogger=debug, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n

shiro.ini

通过Shiro.ini配置文件初始化SecurityManager环境。

[users]
jack=123
rose=123

认证代码

//认证测试
@Test
public void testAuthenticate() {//1.构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");//2.通过工厂创建SecurityManagerSecurityManager securityManager = factory.getInstance();//3.将securityManager设置到运行环境中SecurityUtils.setSecurityManager(securityManager);//4.创建一个Subject实例,该实例认证要使用上边创建的securityManager进行Subject subject = SecurityUtils.getSubject();//5.创建token令牌,记录用户认证的身份和凭证即账号和密码UsernamePasswordToken token = new UsernamePasswordToken("jack", "123");try {//6.用户登陆subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}//7.用户认证状态Boolean isAuthenticated = subject.isAuthenticated();System.out.println("用户认证状态:" + isAuthenticated);//8.用户退出subject.logout();isAuthenticated = subject.isAuthenticated();System.out.println("用户认证状态:" + isAuthenticated);
}
//1.创建SecurityManager
DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
//2.创建设置Realm
IniRealm iniRealm=new IniRealm("classpath:shiro.ini");
defaultSecurityManager.setRealm(iniRealm);
//3.将securityManager设置到运行环境中
SecurityUtils.setSecurityManager(defaultSecurityManager);

认证执行流程

  1. 创建token令牌,token中有用户提交的认证信息即账号和密码

  2. 执行subject.login(token),最终由securityManager通过Authenticator进行认证

  3. Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码,这里使用的是IniRealm(shiro自带)

  4. IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

    shiro授权

授权流程

授权方式

Shiro 支持三种方式的授权:

  1. 编程式:通过写if/else 授权代码块完成:

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {//有权限
} else {//无权限
}
  1. 注解式:通过在执行的Java方法上放置相应的注解完成:

   @RequiresRoles("admin")public void hello() {//有权限}
  1. JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:

<shiro:hasRole name="admin">
<!— 有权限—>
</shiro:hasRole>

与web系统集成使用后两种方式。

授权测试

shiro-permission.ini

创建存放权限的配置文件shiro-permission.ini,如下:

[users]
#用户zhang的密码是123,此用户具有role1和role2两个角色
jack=123,role1,role2
rose=123,role2
[roles]
#角色role1对资源user拥有create、update权限
role1=user:create,user:update
#角色role2对资源user拥有create、delete权限
role2=user:create,user:delete
#角色role3对资源user拥有create权限
role3=user:create

在ini文件中用户、角色、权限的配置规则是:“用户名=密码,角色1,角色2...” “角色=权限1,权限2...”,首先根据用户名找角色,再根据角色找权限,角色是权限集合。

权限字符串规则

权限字符串的规则是:“资源标识符 : 操作”,权限字符串也可以使用*通配符。

例子:
用户创建权限:user:create
用户修改的权限:user:update
用户所有权限:user:*

测试代码

测试代码同认证代码,注意ini地址改为shiro-permission.ini,主要学习下边授权的方法,注意:在用户认证通过后执行下边的授权代码。

//授权测试
@Test
public void testAuthorize() {//1.构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");//2.通过工厂创建SecurityManagerSecurityManager securityManager = factory.getInstance();//3.将securityManager设置到运行环境中SecurityUtils.setSecurityManager(securityManager);//4.创建一个Subject实例,该实例认证要使用上边创建的securityManager进行Subject subject = SecurityUtils.getSubject();//5.创建token令牌,记录用户认证的身份和凭证即账号和密码UsernamePasswordToken token = new UsernamePasswordToken("rose", "123");try {//6.用户登陆subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}//7.用户认证状态Boolean isAuthenticated = subject.isAuthenticated();System.out.println("用户认证状态:" + isAuthenticated);//9.1.用户授权检测 基于角色授权// 是否有某一个角色System.out.println("用户是否拥有一个角色:" + subject.hasRole("role1"));// 是否有多个角色System.out.println("用户是否拥有多个角色:" + subject.hasAllRoles(Arrays.asList("role1", "role2")));//subject.checkRole("role1");//subject.checkRoles(Arrays.asList("role1", "role2"));// 授权检测,失败则抛出异常// subject.checkRole("role22");//9.2基于资源授权System.out.println("是否拥有某一个权限:" + subject.isPermitted("user:delete"));System.out.println("是否拥有多个权限:" + subject.isPermittedAll("user:create", "user:delete"));//检查权限subject.checkPermission("sys:user:delete");subject.checkPermissions("user:create:1","user:delete");//8.用户退出subject.logout();isAuthenticated = subject.isAuthenticated();System.out.println("用户认证状态:" + isAuthenticated);
}

基于角色的授权

//9.1.用户授权检测 基于角色授权
// 是否有某一个角色
System.out.println("用户是否拥有一个角色:" + subject.hasRole("role1"));
// 是否有多个角色
System.out.println("用户是否拥有多个角色:" + subject.hasAllRoles(Arrays.asList("role1", "role2")));//       subject.checkRole("role1");
//      subject.checkRoles(Arrays.asList("role1", "role2"));// 授权检测,失败则抛出异常
// subject.checkRole("role22"); 

上边check方法如果授权失败则抛出异常:

org.apache.shiro.authz.UnauthorizedException: Subject does not have role [.....]

基于资源授权

//9.2基于资源授权
System.out.println("是否拥有某一个权限:" + subject.isPermitted("user:delete"));
System.out.println("是否拥有多个权限:" + subject.isPermittedAll("user:create",  "user:delete"));//检查权限
subject.checkPermission("sys:user:delete");
subject.checkPermissions("user:create:1","user:delete");

上边check方法如果授权失败则抛出异常:

org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [....]

常见的异常

  1. AuthenticationException 异常是Shiro在登录认证过程中,认证失败需要抛出的异常。 AuthenticationException包含以下子类:

1.1 CredentialsException 凭证异常

IncorrectCredentialsException 不正确的凭证 ExpiredCredentialsException 凭证过期

1.2 AccountException 账号异常

ConcurrentAccessException 并发访问异常(多个用户同时登录时抛出) UnknownAccountException 未知的账号 ExcessiveAttemptsException 认证次数超过限制 DisabledAccountException 禁用的账号 LockedAccountException 账号被锁定 pportedTokenException 使用了不支持的Token

  1. AuthorizationException:

2.1 UnauthorizedException: 抛出以指示请求的操作或对请求的资源的访问是不允许的。

2.2 UnanthenticatedException:当尚未完成成功认证时,尝试执行授权操作时引发异常。

自定义Realm

上边的程序使用的是Shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。

提供的realm

最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权,通常自定义的realm继承AuthorizingRealm。

自定义Realm

public class CustomRealm1 extends AuthorizingRealm {@Overridepublic String getName() {return "customRealm1";}//支持UsernamePasswordToken@Overridepublic boolean supports(AuthenticationToken token) {return token instanceof UsernamePasswordToken;}//认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//从token中 获取用户身份信息String username = (String) token.getPrincipal();//拿username从数据库中查询//....//如果查询不到则返回nullif(!username.equals("jack")){//这里模拟查询不到return null;}//获取从数据库查询出来的用户密码String password = "123";//这里使用静态数据模拟。。//返回认证信息由父类AuthenticatingRealm进行认证SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, getName());return simpleAuthenticationInfo;}//授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubreturn null;}}

shiro-realm.ini

[main]
#自定义 realm
customRealm=com.zking.shiro.realm.CustomRealm1
#将realm设置到securityManager
securityManager.realms=$customRealm

思考:这里为什么不用配置[users]了??

测试代码

测试代码同入门程序,将ini的地址修改为shiro-realm.ini。

分别模拟账号不存在、密码错误、账号和密码正确进行测试。

散列算法

​ 散列算法一般用于生成一段文本的摘要信息,散列算法不可逆,将内容可以生成摘要,无法将摘要转成原始内容。散列算法常用于对密码进行散列,常用的散列算法有MD5、SHA。

一般散列算法需要提供一个salt(盐)与原始内容生成摘要信息,这样做的目的是为了安全性,比如:123的md5值是:202cb962ac59075b964b07152d234b70,拿着“202cb962ac59075b964b07152d234b70”去md5破解网站很容易进行破解,如果要是对123和salt(盐,一个随机数)进行散列,这样虽然密码都是123加不同的盐会生成不同的散列值。

例子

   @Testpublic void testMd5(){//md5加密,不加盐String password_md5 = new Md5Hash("123").toString();System.out.println("md5加密,不加盐="+password_md5);//md5加密,加盐,一次散列String password_md5_sale_1 = new Md5Hash("123", "eteokues", 1).toString();System.out.println("password_md5_sale_1="+password_md5_sale_1);String password_md5_sale_2 = new Md5Hash("123", "uiwueylm", 1).toString();System.out.println("password_md5_sale_2="+password_md5_sale_2);//两次散列相当于md5(md5())//使用SimpleHashString simpleHash = new SimpleHash("MD5", "123", "eteokues",1).toString();System.out.println(simpleHash);}

在realm中使用md5

实际应用是将盐和散列后的值存在数据库中,自动realm从数据库取出盐和加密后的值由shiro完成密码校验。

自定义realm

 //认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//用户账号String username = (String) token.getPrincipal();//根据用户账号从数据库取出盐和加密后的值//..这里使用静态数据//如果根据账号没有找到用户信息则返回null,shiro抛出异常“账号不存在”//按照固定规则加密码结果 ,此密码 要在数据库存储,原始密码 是123,盐是eteokuesString password = "fd4613f37bb1805db10acf1768fb8d76";//盐,随机数,此随机数也在数据库存储String salt = "eteokues";//返回认证信息SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, ByteSource.Util.bytes(salt),getName());return simpleAuthenticationInfo;}

realm配置

[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1
#将凭证匹配器设置到realm
customRealm=com.zking.shiro.realm2.CustomRealm2
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm

测试代码

测试代码同上个章节,注意修改ini路径。

自定义realm-授权

​ 与上边认证自定义realm一样,大部分情况是要从数据库获取权限数据,这里直接实现基于资源的授权。

realm代码

在认证章节写的自定义realm类中完善doGetAuthorizationInfo方法,此方法需要完成:根据用户身份信息从数据库查询权限字符串,由shiro进行授权。

   //授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 获取身份信息String username = (String) principals.getPrimaryPrincipal();// 根据身份信息从数据库中查询权限数据//....这里使用静态数据模拟List<String> permissions = new ArrayList<String>();permissions.add("user:create");permissions.add("user.delete");//将权限信息封闭为AuthorizationInfoSimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();for(String permission:permissions){simpleAuthorizationInfo.addStringPermission(permission);}return simpleAuthorizationInfo;}

shiro-realm-md5.ini

ini配置文件还使用认证阶段使用的,不用改变。

思考:shiro-permission.ini中的[roles]为什么不需要了??

测试代码

同上边的授权测试代码,注意修改ini地址为shiro-realm.ini或者shiro-realm-md5.ini。

 // 自定义realm进行资源授权测试@Testpublic void testAuthorizationCustomRealm() {//1.构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-cryptography2.ini");//2.通过工厂创建SecurityManagerSecurityManager securityManager = factory.getInstance();//3.将securityManager设置到运行环境中SecurityUtils.setSecurityManager(securityManager);//4.创建一个Subject实例,该实例认证要使用上边创建的securityManager进行Subject subject = SecurityUtils.getSubject();//5.创建token令牌,记录用户认证的身份和凭证即账号和密码UsernamePasswordToken token = new UsernamePasswordToken("jack", "123");try {//6.用户登陆subject.login(token);} catch (AuthenticationException e) {// TODO Auto-generated catch blocke.printStackTrace();}//7.用户认证状态Boolean isAuthenticated = subject.isAuthenticated();System.out.println("用户认证状态:" + isAuthenticated);// 认证通过后执行授权// 基于资源的授权,调用isPermitted方法会调用CustomRealm从数据库查询正确权限数据// isPermitted传入权限标识符,判断user:create:1是否在CustomRealm查询到权限数据之内boolean isPermitted = subject.isPermitted("user:create");System.out.println("单个权限判断" + isPermitted);boolean isPermittedAll = subject.isPermittedAll("user:create", "user:delete");System.out.println("多个权限判断" + isPermittedAll);// 使用check方法进行授权,如果授权不通过会抛出异常subject.checkPermission("items:add");}

授权执行流程

  1. 对subject进行授权,调用subject.isPermitted("user:create")

  2. securityManager执行授权,通过ModularRealmAuthorizer进行授权

  3. ModularRealmAuthorizer调用realm从数据库查询权限数据,调用realm的授权方法:doGetAuthorizationInfo

  4. realm 从数据库查询权限数据,返回给ModularRealmAuthorizer

  5. ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

  6. 比对后,如果isPermiited中的"permission"串在realm查询到权限数据中,说明用户访问permission串有权限,否则没有权限,执行异常

shiro与项目集成

添加jar包

同上

web.xml添加shiro Filter

 <!-- shiro过虑器,DelegatingFilterProx会从spring容器中找id为shiroFilter的bean  --><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><init-param><!--targetFilterLifecycle=true指明作用于filter的所有生命周期--><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>

applicationContext-shiro.xml

 <!--配置自定义的Realm--><bean id="shiroRealm" class="com.zking.ssm.shiro.UserRealm"><property name="credentialsMatcher"><bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><!--指定hash算法为MD5--><property name="hashAlgorithmName" value="md5"/><!--指定散列次数为1024次--><property name="hashIterations" value="1024"/><!--true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储--><property name="storedCredentialsHexEncoded" value="true"/></bean></property></bean><!--注册安全管理器--><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="shiroRealm" /></bean><!--Shiro核心过滤器--><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- Shiro的核心安全接口,这个属性是必须的 --><property name="securityManager" ref="securityManager" /><!-- 身份验证失败,跳转到登录页面 --><property name="loginUrl" value="/login"/><!-- 身份验证成功,跳转到指定页面 --><!--<property name="successUrl" value="/index.jsp"/>--><!-- 权限验证失败,跳转到指定页面,注只对AuthorizationFilter有效--><!--<property name="unauthorizedUrl" value="/refuse.jsp"/>--><!-- Shiro连接约束配置,即过滤链的定义 --><property name="filterChainDefinitions"><value><!--注:anon,authcBasic,auchc,user是认证过滤器perms,roles,ssl,rest,port是授权过滤器--><!--anon 表示匿名访问,不需要认证以及授权--><!--authc表示需要认证 没有进行身份认证是不能进行访问的--><!--roles[admin]表示角色认证,必须是拥有admin角色的用户才行-->/user/login=anon/api/login=anon/common/**=authc/admin/**=authc/api/**=anon</value></property></bean>

使用shiro注解授权

 @RequiresRoles(value = {"admin"})@RequestMapping("/list")public String list(@ModelAttribute(name = "user") User user, @RequestParam(defaultValue = "1") Integer pageIndex, Model model){

自定义realm

public class UserRealm extends AuthorizingRealm {private Logger log = Logger.getLogger(UserRealm.class);@Resourceprivate SysUserService sysUserService;/*** 授权* 验证通过后获取用户拥有的角色信息和权限信息* @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//获取用户名String userName = principalCollection.getPrimaryPrincipal().toString();//生成授权信息对象SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();//设置用户拥有角色authorizationInfo.addRoles(sysUserService.findRolesByUserName(userName));//设置用户拥有权限/* authorizationInfo.setStringPermissions(userService.getPermissionsByUserName(userName));*/return authorizationInfo;}/*** 认证* 从数据库抓取用户密码凭证交给Shiro进行验证* @param token 认证对象,可以获取* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {log.debug("认证...");String userName = String.valueOf(token.getPrincipal());if(userName==null){throw new UnknownAccountException();}SysUser sysUser  = sysUserService.findByUserName(userName);//账户不存在if(ObjectUtils.isEmpty(sysUser)) {throw new UnknownAccountException();}//不考虑加密/*  SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserCode(),user.getUserPassword(),this.getName());*///考虑加密,在applicationContext-shiro.xml中shiroReal添加如下配置/*  <property name="credentialsMatcher"><bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><!--指定hash算法为MD5--><property name="hashAlgorithmName" value="md5"/><!--指定散列次数为1024次--><property name="hashIterations" value="1024"/><!--true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储--><property name="storedCredentialsHexEncoded" value="true"/></bean></property>*/SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(sysUser.getUsername(),sysUser.getPassword(),ByteSource.Util.bytes(sysUser.getSalt()),this.getName());return authenticationInfo;}}

登入/登出

@Controller
public class LoginController {@RequestMapping("/login")public String login(User user, Model model){Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(user.getUserCode(), user.getUserPassword());try {subject.login(token);} catch (AuthenticationException ex) {model.addAttribute("message", "账户或密码错误");return "login";}return "redirect:admin/user/list";}@RequestMapping("/logout")public String logout(){Subject subject = SecurityUtils.getSubject();subject.logout();return "redirect:login";}
}

shiro过滤器

过滤器简称 对应的java类
anon org.apache.shiro.web.filter.authc.AnonymousFilter
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port org.apache.shiro.web.filter.authz.PortFilter
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl org.apache.shiro.web.filter.authz.SslFilter
user org.apache.shiro.web.filter.authc.UserFilter
logout org.apache.shiro.web.filter.authc.LogoutFilter

anon:例子/admins/**=anon 没有参数,表示可以匿名使用。

authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,没有参数

roles:例子/admins/user/=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。

perms:例子/admins/user/=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/=perms["user:add:,user:modify:"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。

rest:例子/admins/user/=rest[user],根据请求的方法,相当于/admins/user/=perms[user:method] ,其中method为post,get,delete等。

port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString

是你访问的url里的?后面的参数。

authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证

ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https

user:例如/admins/user/**=user没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查

注:

anon,authcBasic,auchc,user是认证过滤器,

perms,roles,ssl,rest,port是授权过滤器

Shiro认证和授权相关推荐

  1. shiro认证与授权

    1.shiro认证 1.1.身份验证 身份验证:一般需要提供如身份ID等一些标识信息来表明登录者的身份,如提供email,用户名/密码来证明. 在shiro中,用户需要提供principals(身份) ...

  2. Shiro认证和授权的思路

    认证 (1)获取当前的Subject,调用SecurityUtils.getSubject(): (2)测试当前的用户是否已经被认证,即是否已经登录.调用Subject的isAuthenticated ...

  3. shiro认证与授权:自定义realm

    [main] #声明realm permReam=cn.learn.shiro.PermissionRealm #注册realm到securityManager中 securityManager.re ...

  4. shiro认证与授权:基于ini的用户授权

    [users] #用户名=密码,角色名 zhangsan=123456,role1,role2 lisi=123456,role2 [roles] #角色 #角色名=权限列表 role1=user:s ...

  5. 源码分析shiro认证授权流程

    1. shiro介绍 Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录": 授权 - ...

  6. Springboot整合shiro基于url身份认证和授权认证

    你还不会shiro吗? 前奏 shiro核心配置文件(rolesFilter可选). 身份认证 多表登录源如何操作? 授权管理 如何解决界面多角色/资源问题 访问效果 权限管理在日常开发中很重要,所以 ...

  7. authc过滤器 shiro_使用Shiro实现认证和授权(基于SpringBoot)

    Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案.下面是在SpringBoot中使用Shiro进行认证和授权 ...

  8. Shiro+springboot+mybatis+EhCache(md5+salt+散列)认证与授权-03

    从上文:Shiro+springboot+mybatis(md5+salt+散列)认证与授权-02 当每次进行刷新时,都会从数据库重新查询数据进行授权操作,这样无疑给数据库造成很大的压力,所以需要引入 ...

  9. Shiro+springboot+mybatis(md5+salt+散列)认证与授权-02

    代码延续地址:Shiro+springboot+mybatis(md5+salt+散列)认证与授权-01 1.创建t_role角色表(比如管理员admin,普通用户user等),创建t_pers权限表 ...

最新文章

  1. 图解|打工人看腾讯这道多线程面试题
  2. poj 1436 zoj 1391 Horizontally Visible Segments (Segment Tree)
  3. 数据采集之用户区域(USER)事件
  4. C#调用WebService实例和开发(转)
  5. ORA-01089 数据库无法正常关闭
  6. 【代码+论文】基于自适应排序学习的个性化推荐方法
  7. Spring----AOP的术语
  8. SM4算法的C++实现(代码)
  9. 字节岗位的薪酬体系曝光,看完感叹:真的不服不行
  10. 传世调试之-道士技能《解毒术》、《神光术》:无法正常升级。
  11. 《丑奴儿书博山道中壁》
  12. HC74h595 串行输出再进行串口输出(串行通信嵌套)已测试成功。
  13. CSS 相邻兄弟选择器
  14. IDEA不同颜色文件代表的意思
  15. gfsj(getit)
  16. 推荐6款高效率PDF编辑工具
  17. 工程热力学学习笔记DE-2. Erster Hauptsatz der Thermodynamik
  18. csrf(csrf请求非法是什么意思)
  19. 爬虫系列之链家的信息爬取及数据分析
  20. 云枢认证考试_云枢互动下载

热门文章

  1. 三星SCX-4521F 如何清洁搓纸轮?
  2. winform手绘Step步骤进度节点线条图
  3. 2.php函数,PHP函数索引(2)
  4. Zend Framework教程-Zend_View
  5. c语言如何输出三角函数公式大全,用C语言打印出三角函数
  6. IPMI之KCS驱动接口
  7. win11系统 打开Bitlocker加密的分区,输入密码后提示位置不可用“无法访问 参数错误”
  8. 基于大数据的城市可视化治理:辅助决策模型与应用
  9. 如何从官网下载KEIL MDK5软件
  10. 台式win7f1到f12热键取消_win7系统关闭f1-f12功能键的操作方法