Shiro认证

1配置文件,(*.ini,*,xml ,或者配置类)后面细讲

一,登陆,登出过程

1,根据配置文件,生成SecurityManager工厂   Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");  

2,从工厂中获取SecurityManager实例

org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();  

3,把实例绑定到SecurityUtils

 SecurityUtils.setSecurityManager(securityManager);  

4,获取Subject对象,Subject subject=SecurityUtils.getSubject();

5,获取登陆token,UsernamePasswordToken token =new UsernamePasswordToken("zhang", "123");  

6,subject.login(token);

7,subject.logout();

二,login()方法流程

Shiro认证_第1张图片

流程如下:

1、首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必须通过SecurityUtils. setSecurityManager()设置;

2、SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;

3、Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自定义插入自己的实现;

4、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;

5、Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

三,Realm

可以理解为,用哪的数据(用数据库的数据,内存的,或者其他地方的数据),验证登陆的方法(具体的验证实现)

org.apache.shiro.realm.Realm接口如下: 有3个方法

String getName(); //返回一个唯一的Realm名字  

boolean supports(AuthenticationToken token); //判断此Realm是否支持此Token  

AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)  (验证的逻辑,根据自己的情况重写)

throws AuthenticationException;  //根据Token获取认证信息  


public class MyRealm1 implements Realm {  

@Override  

public String getName() {  

return "myrealm1";  

    }  

@Override  

public boolean supports(AuthenticationToken token) {  

//仅支持UsernamePasswordToken类型的Token  

return token instanceof UsernamePasswordToken;   

    }  

@Override  

public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  

String username = (String)token.getPrincipal();//得到用户名  

String password =new String((char[])token.getCredentials()); //得到密码  

if(!"zhang".equals(username)) {  

throw new UnknownAccountException(); //如果用户名错误  

        }  

if(!"123".equals(password)) {  

throw new IncorrectCredentialsException(); //如果密码错误  

        }  

//如果身份认证验证成功,返回一个AuthenticationInfo实现;  

return new SimpleAuthenticationInfo(username, password, getName());  

    }  

}   

在配置文件中配置用那个Realm类

#声明一个realm  

myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1  

#指定securityManager的realms实现  

securityManager.realms=$myRealm1   


也可以配置多个Realm

#声明一个realm  

myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1  

myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2  

#指定securityManager的realms实现  

securityManager.realms=$myRealm1,$myRealm2   

SecurityManager会按照Realm得顺序去验证,此处我们使用显示指定顺序的方式指定了Realm的顺序,如果删除“securityManager.realms=$myRealm1,$myRealm2”,那么securityManager会按照realm声明的顺序进行使用(即无需设置realms属性,其会自动发现),当我们显示指定realm后,其他没有指定realm将被忽略,如“securityManager.realms=$myRealm1”,那么myRealm2不会被自动设置进去。

Shiro默认提供的Realm

Shiro认证_第2张图片

以后一般继承AuthorizingRealm(授权)即可;其继承了AuthenticatingRealm(即身份验证),而且也间接继承了CachingRealm(带有缓存实现)。其中主要默认实现如下:

org.apache.shiro.realm.text.IniRealm[users]部分指定用户名/密码及其角色;[roles]部分指定角色即权限信息;

org.apache.shiro.realm.text.PropertiesRealm user.username=password,role1,role2指定用户名/密码及其角色;role.role1=permission1,permission2指定角色及权限信息;

org.apache.shiro.realm.jdbc.JdbcRealm通过sql查询相应的信息,如“select password from users where username = ?”获取用户密码,“select password, password_salt from users where username = ?”获取用户密码及盐;“select role_name from user_roles where username = ?”获取用户角色;“select permission from roles_permissions where role_name = ?”获取角色对应的权限信息;也可以调用相应的api进行自定义sql;

上面说的是几种Realm类型,一般我们重写的时候,继承AuthorizingRealm就可以了,重写里面的方法,现在一般是从方法,或者接口取用户信息

JDBC Realm使用

1,Maven添加数据驱动引用

2,在配置文件里配饰数据库配置 ,(shiro-jdbc-realm.ini) 

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm  

dataSource=com.alibaba.druid.pool.DruidDataSource  

dataSource.driverClassName=com.mysql.jdbc.Driver  

dataSource.url=jdbc:mysql://localhost:3306/shiro  

dataSource.username=root  

#dataSource.password=  

jdbcRealm.dataSource=$dataSource  

securityManager.realms=$jdbcRealm   

1、变量名=全限定类名会自动创建一个类实例

2、变量名.属性=值 自动调用相应的setter方法进行赋值

3、$变量名 引用之前的一个对象实例

2.6 Authenticator及AuthenticationStrategy

Authenticator的职责是验证用户帐号,是Shiro API中身份验证核心的入口点: 

public AuthenticationInfo authenticate(AuthenticationToken authenticationToken)  

throws AuthenticationException;   

如果验证成功,将返回AuthenticationInfo验证信息;此信息中包含了身份及凭证;如果验证失败将抛出相应的AuthenticationException实现。

SecurityManager接口继承了Authenticator,另外还有一个ModularRealmAuthenticator(Authenticator接口的实现类)实现,其委托给多个Realm进行验证,验证规则通过AuthenticationStrategy接口指定,默认提供的实现:

FirstSuccessfulStrategy:只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略;

AtLeastOneSuccessfulStrategy:只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,返回所有Realm身份验证成功的认证信息;

AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。

配置文件中,指定 authenticator实现,还有指定验证策略(authenticationStrategy)

#指定securityManager的authenticator实现  

authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator  

securityManager.authenticator=$authenticator  

#指定securityManager.authenticator的authenticationStrategy  

allSuccessfulStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy  

securityManager.authenticator.authenticationStrategy=$allSuccessfulStrategy  

配置Realm,只用了1,2

.myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1  

myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2  

myRealm3=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm3  

securityManager.realms=$myRealm1,$myRealm3  

注意:如果有多个认证Realm需要配置authenticationStrategy  

你可能感兴趣的:(Shiro认证)