Shiro学习随笔【二】身份认证
2017-09-14 13:32
183 查看
一、身份认证也就是提供相应的凭证证明你是用户本人,通常是指用户名和密码,在Shiro中用户需要体用Principals(身份)、Credentials(证明)给shiro,从而能够验证用户的身份。
Principals:身份,即主题的标识属性,可以有多个如邮箱、手机号、用户名等,但是只能有一个主身份标识。
Credentials:证明/凭证,即用户的密码或者数字证书。
二、用户的登录和退出
首先新增配置文件shiro.ini,在配置文件中新增:zhang=123
验证用户登录和退出的代码如下:
package shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Description:TODO
* @version 1.0
* @since JDK1.7
* @author yaomy
* @company xxxxxxxxxxxxxx
* @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved.
* @date 2017年9月13日 下午4:37:09
*/
public class LoginOutDemo {
private static final transient Logger log = LoggerFactory.getLogger(LoginOutDemo.class);
public static void main(String[] args) {
//获取SecurityManager安全管理器工厂类,此处使用shiro.ini文件进行初始化
Factory<SecurityManager> factory = new IniSecurityManagerFactory("conf/shiro.ini");
//获取SecurityManager安全管理器实例,并绑定给SecurityUtils
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//获取主题
Subject subject = SecurityUtils.getSubject();
//创建用户名密码身份验证token(即:用户身份/凭证)
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
token.setRememberMe(true);
try{
//登录,即身份验证
subject.login(token);
log.info("登录成功");
} catch(AuthenticationException e){
log.info("身份验证失败"+e);
}
subject.logout();
}
}
执行的结果如下:
11:50:11,085 INFO ~ Enabling session validation scheduler...
11:50:11,139 INFO ~ 登录成功
以上代码是从配置文件中读取用户的信息,下面接着讲从单个Realm中读取用户数据
三、Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
自定义Realm实现:
package shiro;
import java.util.Arrays;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
/**
* 单个Realm配置
* @Description:域,Shiro从从Realm获取安全数据(如用户、角色、权限)
* @version 1.0
* @since JDK1.7
* @author yaomy
* @company xxxxxxxxxxxxxx
* @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved.
* @date 2017年9月13日 下午6:03:43
*/
public class MyRealm implements Realm{
/**
*
* @Description:返回唯一的Realm名字
* @author yaomy
* @date 2017年9月13日 下午6:04:21
*/
@Override
public String getName() {
// TODO Auto-generated method stub
return "myrealm";
}
/**
*
* @Description:判断此Realm是否支持此token
* @author yaomy
* @date 2017年9月13日 下午6:04:43
*/
@Override
public boolean supports(AuthenticationToken token) {
// 仅支持UsernamePasswordToken类型的token
return token instanceof UsernamePasswordToken;
}
/**
*
* @Description:根据token获取认证信息
* @author yaomy
* @date 2017年9月13日 下午6:05:20
*/
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
String username = (String)token.getPrincipal();//用户名(认证)
String password = new String((char[])token.getCredentials());//用
ddfa
户密码(凭证)
if(!username.equals("zhang")){
throw new UnknownAccountException();
}
if(!password.equals("123")){
throw new IncorrectCredentialsException();
}
return new SimpleAuthenticationInfo(username, password, getName());
}
}
定义配置文件shiro-realm.ini
myrealm=shiro.MyRealm
securityManager.realms=$myrealm
测试Realm代码如下:
执行测试代码:
11:57:09,203 INFO ~ Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur.
11:57:09,213 INFO ~ Enabling session validation scheduler...
11:57:09,247 INFO ~ 登录成功
四、多个Realm
Authenticator的职责是验证用户帐号,是Shiro API中身份验证核心的入口点,如果验证成功,将返回AuthenticationInfo验证信息;此信息中包含了身份及凭证;如果验证失败将抛出相应的AuthenticationException实现。
SecurityManager接口继承了Authenticator,另外还有一个ModularRealmAuthenticator实现,其委托给多个Realm进行验证,验证规则通过AuthenticationStrategy接口指定,默认提供的实现:
FirstSuccessfulStrategy:只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略;
AtLeastOneSuccessfulStrategy:只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,返回所有Realm身份验证成功的认证信息;
AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。
ModularRealmAuthenticator默认使用AtLeastOneSuccessfulStrategy策略。
配置文件shiro-realm.ini
#指定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
myrealm=shiro.MyRealm
myrealm2=shiro.MyRealm2
securityManager.realms=$myrealm,$myrealm2
测试代码:
package shiro;
import java.util.Arrays;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
/**
* 单个Realm配置
* @Description:域,Shiro从从Realm获取安全数据(如用户、角色、权限)
* @version 1.0
* @since JDK1.7
* @author yaomy
* @company xxxxxxxxxxxxxx
* @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved.
* @date 2017年9月13日 下午6:03:43
*/
public class MyRealm2 implements Realm{
/**
*
* @Description:返回唯一的Realm名字
* @author yaomy
* @date 2017年9月13日 下午6:04:21
*/
@Override
public String getName() {
// TODO Auto-generated method stub
return "myrealm2";
}
/**
*
* @Description:判断此Realm是否支持此token
* @author yaomy
* @date 2017年9月13日 下午6:04:43
*/
@Override
public boolean supports(AuthenticationToken token) {
// 仅支持UsernamePasswordToken类型的token
return token instanceof UsernamePasswordToken;
}
/**
*
* @Description:根据token获取认证信息
* @author yaomy
* @date 2017年9月13日 下午6:05:20
*/
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
String username = (String)token.getPrincipal();//用户名(认证)
String password = new String((char[])token.getCredentials());//用户密码(凭证)
if(!username.equals("zhang")){
throw new UnknownAccountException();
}
if(!password.equals("123")){
throw new IncorrectCredentialsException();
}
return new SimpleAuthenticationInfo(username, password, getName());
}
}
Principals:身份,即主题的标识属性,可以有多个如邮箱、手机号、用户名等,但是只能有一个主身份标识。
Credentials:证明/凭证,即用户的密码或者数字证书。
二、用户的登录和退出
首先新增配置文件shiro.ini,在配置文件中新增:zhang=123
验证用户登录和退出的代码如下:
package shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Description:TODO
* @version 1.0
* @since JDK1.7
* @author yaomy
* @company xxxxxxxxxxxxxx
* @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved.
* @date 2017年9月13日 下午4:37:09
*/
public class LoginOutDemo {
private static final transient Logger log = LoggerFactory.getLogger(LoginOutDemo.class);
public static void main(String[] args) {
//获取SecurityManager安全管理器工厂类,此处使用shiro.ini文件进行初始化
Factory<SecurityManager> factory = new IniSecurityManagerFactory("conf/shiro.ini");
//获取SecurityManager安全管理器实例,并绑定给SecurityUtils
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//获取主题
Subject subject = SecurityUtils.getSubject();
//创建用户名密码身份验证token(即:用户身份/凭证)
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
token.setRememberMe(true);
try{
//登录,即身份验证
subject.login(token);
log.info("登录成功");
} catch(AuthenticationException e){
log.info("身份验证失败"+e);
}
subject.logout();
}
}
执行的结果如下:
11:50:11,085 INFO ~ Enabling session validation scheduler...
11:50:11,139 INFO ~ 登录成功
以上代码是从配置文件中读取用户的信息,下面接着讲从单个Realm中读取用户数据
三、Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
自定义Realm实现:
package shiro;
import java.util.Arrays;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
/**
* 单个Realm配置
* @Description:域,Shiro从从Realm获取安全数据(如用户、角色、权限)
* @version 1.0
* @since JDK1.7
* @author yaomy
* @company xxxxxxxxxxxxxx
* @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved.
* @date 2017年9月13日 下午6:03:43
*/
public class MyRealm implements Realm{
/**
*
* @Description:返回唯一的Realm名字
* @author yaomy
* @date 2017年9月13日 下午6:04:21
*/
@Override
public String getName() {
// TODO Auto-generated method stub
return "myrealm";
}
/**
*
* @Description:判断此Realm是否支持此token
* @author yaomy
* @date 2017年9月13日 下午6:04:43
*/
@Override
public boolean supports(AuthenticationToken token) {
// 仅支持UsernamePasswordToken类型的token
return token instanceof UsernamePasswordToken;
}
/**
*
* @Description:根据token获取认证信息
* @author yaomy
* @date 2017年9月13日 下午6:05:20
*/
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
String username = (String)token.getPrincipal();//用户名(认证)
String password = new String((char[])token.getCredentials());//用
ddfa
户密码(凭证)
if(!username.equals("zhang")){
throw new UnknownAccountException();
}
if(!password.equals("123")){
throw new IncorrectCredentialsException();
}
return new SimpleAuthenticationInfo(username, password, getName());
}
}
定义配置文件shiro-realm.ini
myrealm=shiro.MyRealm
securityManager.realms=$myrealm
测试Realm代码如下:
package shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * http://jinnianshilongnian.iteye.com/blog/2019547 * @Description:TODO * @version 1.0 * @since JDK1.7 * @author yaomy * @company xxxxxxxxxxxxxx * @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved. * @date 2017年9月13日 下午4:37:09 */ public class RealmDemo { private static final transient Logger log = LoggerFactory.getLogger(RealmDemo.class); public static void main(String[] args) { //获取SecurityManager安全管理器工厂类,此处使用shiro.ini文件进行初始化 Factory<SecurityManager> factory = new IniSecurityManagerFactory("conf/shiro-realm.ini"); //获取SecurityManager安全管理器实例,并绑定给SecurityUtils SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //获取主题 Subject subject = SecurityUtils.getSubject(); //创建用户名密码身份验证token(即:用户身份/凭证) UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123", true); try{ //登录,即身份验证 subject.login(token); log.info("登录成功"); } catch(AuthenticationException e){ log.info("身份验证失败"+e); } subject.logout(); } }
执行测试代码:
11:57:09,203 INFO ~ Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur.
11:57:09,213 INFO ~ Enabling session validation scheduler...
11:57:09,247 INFO ~ 登录成功
四、多个Realm
Authenticator的职责是验证用户帐号,是Shiro API中身份验证核心的入口点,如果验证成功,将返回AuthenticationInfo验证信息;此信息中包含了身份及凭证;如果验证失败将抛出相应的AuthenticationException实现。
SecurityManager接口继承了Authenticator,另外还有一个ModularRealmAuthenticator实现,其委托给多个Realm进行验证,验证规则通过AuthenticationStrategy接口指定,默认提供的实现:
FirstSuccessfulStrategy:只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略;
AtLeastOneSuccessfulStrategy:只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,返回所有Realm身份验证成功的认证信息;
AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。
ModularRealmAuthenticator默认使用AtLeastOneSuccessfulStrategy策略。
配置文件shiro-realm.ini
#指定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
myrealm=shiro.MyRealm
myrealm2=shiro.MyRealm2
securityManager.realms=$myrealm,$myrealm2
测试代码:
package shiro;
import java.util.Arrays;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
/**
* 单个Realm配置
* @Description:域,Shiro从从Realm获取安全数据(如用户、角色、权限)
* @version 1.0
* @since JDK1.7
* @author yaomy
* @company xxxxxxxxxxxxxx
* @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved.
* @date 2017年9月13日 下午6:03:43
*/
public class MyRealm2 implements Realm{
/**
*
* @Description:返回唯一的Realm名字
* @author yaomy
* @date 2017年9月13日 下午6:04:21
*/
@Override
public String getName() {
// TODO Auto-generated method stub
return "myrealm2";
}
/**
*
* @Description:判断此Realm是否支持此token
* @author yaomy
* @date 2017年9月13日 下午6:04:43
*/
@Override
public boolean supports(AuthenticationToken token) {
// 仅支持UsernamePasswordToken类型的token
return token instanceof UsernamePasswordToken;
}
/**
*
* @Description:根据token获取认证信息
* @author yaomy
* @date 2017年9月13日 下午6:05:20
*/
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
String username = (String)token.getPrincipal();//用户名(认证)
String password = new String((char[])token.getCredentials());//用户密码(凭证)
if(!username.equals("zhang")){
throw new UnknownAccountException();
}
if(!password.equals("123")){
throw new IncorrectCredentialsException();
}
return new SimpleAuthenticationInfo(username, password, getName());
}
}
package shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * http://jinnianshilongnian.iteye.com/blog/2019547 * @Description:TODO * @version 1.0 * @since JDK1.7 * @author yaomy * @company xxxxxxxxxxxxxx * @copyright (c) 2017 yaomy Co'Ltd Inc. All rights reserved. * @date 2017年9月13日 下午4:37:09 */ public class RealmDemo { private static final transient Logger log = LoggerFactory.getLogger(RealmDemo.class); public static void main(String[] args) { //获取SecurityManager安全管理器工厂类,此处使用shiro.ini文件进行初始化 Factory<SecurityManager> factory = new IniSecurityManagerFactory("conf/shiro-realm.ini"); //获取SecurityManager安全管理器实例,并绑定给SecurityUtils SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //获取主题 Subject subject = SecurityUtils.getSubject(); //创建用户名密码身份验证token(即:用户身份/凭证) UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123", true); try{ //登录,即身份验证 subject.login(token); log.info("登录成功"); } catch(AuthenticationException e){ log.info("身份验证失败"+e); } subject.logout(); } }
相关文章推荐
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证