Shiro最佳实践(四)基于ini配置文件的自定义认证
Apache Shiroadmin 发布于:2019-08-03 22:56:23
阅读:loading
本文所谓的基于ini配置文件的自定义认证是从ini文件中定义用户账户及角色权限信息,通过自己实现Realm的方式进行登录授权,比较简单,参考具体如下:
#按用户名与密码登录
[users]
chendd=www.chendd.cn,admin,manager
[roles]
admin=*
manager="user:insert,update,delete","concat:*"
package cn.chendd.shiro.custom;
import ...;
/**
* @author chendd
* 自定义登录认证实现
*/
public class LoginRealm extends IniRealm {
Logger logger = LoggerFactory.getLogger(this.getClass());
public LoginRealm(String resourcePath) {
super(resourcePath);
}
/**
* 自定义认证器名称
*/
@Override
public String getName() {
return "chendd-login-realem";
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
logger.debug("待认证的用户名为:{},密码为:{}" ,
userToken.getUsername() , userToken.getPassword());
SimpleAccount account = this.getUser(userToken.getUsername());
if(account == null){
throw new UnknownAccountException("用户不存在!");
}
if(! account.getCredentials().toString().equals(new String(userToken.getPassword()))){
throw new AuthenticationException("用户名或密码不匹配!");
}
Object credentials = account.getCredentials();
Object principal = token.getPrincipal();
//将用户account对象存储至用户账号主体中
SimpleAuthenticationInfo authInfo = new SimpleAuthenticationInfo(account , credentials , this.getName());
return authInfo;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取主体用户账号信息,将账号中的角色、权限信息进行授权
SimpleAccount account = (SimpleAccount) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo simpleAuthor = new SimpleAuthorizationInfo();
System.out.println(simpleAuthor.getRoles());
simpleAuthor.setRoles((Set<String>) account.getRoles());
simpleAuthor.setObjectPermissions((Set<Permission>) account.getObjectPermissions());
return simpleAuthor;
}
}
package cn.chendd.shiro.examples.login;
import ...;
/**
* @author chendd
* 自定义登录验证器(模拟从数据库中获取账号登录)
*/
public class LoginRealmTest extends LoginTest {
@Test
public void testLoginRealm() {
logger.info("###测试自定义认证器登录--用户名 {} ,密码 {} ###" , username , password);
String resourcePath = "classpath:shiro/shiro-loginRealm.ini";
Realm realm = new LoginRealm(resourcePath);
SecurityManager securityManager = new DefaultSecurityManager(realm);
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
Subject loginSubject = securityManager.login(subject, token);
if (loginSubject.isAuthenticated()) {
logger.debug("用户已经认证");
}
logger.info("用户名 {} 认证成功", loginSubject.getPrincipal());
logger.info("是否拥有角色manager:{}", loginSubject.hasRole("manager"));
logger.info("是否拥有联系人查询权限:{}", loginSubject.isPermitted("concat:select"));
} catch (AuthenticationException e) {
logger.error("用户名 {} 认证失败", username, e);
}
}
}
package cn.chendd.shiro.custom;
import ...
/**
* 自定义用户、角色、权限认证器
* @author chendd
*/
public class PrimisionRealm extends IniRealm {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public String getName() {
return "chendd-primision-realm";
}
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo author = new SimpleAuthorizationInfo();
String userName = (String) principals.getPrimaryPrincipal();
logger.debug("###构造用户[{}]的角色权限授权信息###" , userName);
Set<String> roles = new HashSet<>();//角色集合
Set<String> primisions = new HashSet<>();//权限集合
if("admin".equals(userName)){
roles.add("admin");//管理员角色,任意权限
primisions.add("*");
} else if("chendd".equals(userName)){
roles.add("coder");//coder角色及权限
primisions.add("usermanager:*");
primisions.add("logmanager:select");
primisions.add("menumanager:insert");
primisions.add("menumanager:delete");
roles.add("tester");//tester角色及权限
primisions.add("menumanager:test:test");
primisions.add("menumanager:insert");
} else if("tt".equals(userName)){
roles.add("tester");//tester角色及权限
primisions.add("menumanager:test:test");
primisions.add("menumanager:insert");
} else {
throw new AuthenticationException("用户名与密码不匹配!");
}
author.addRoles(roles);
author.addStringPermissions(primisions);
return author;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
String userName = userToken.getUsername();
String password = new String(userToken.getPassword());
boolean flag = false;
if("admin".equals(userName) && "admin123".equals(password)){
flag = true;
} else if("chendd".equals(userName) && "chendd123".equals(password)){
flag = true;
} else if("tt".equals(userName) && "tt123".equals(password)){
flag = true;
} else {
throw new AuthenticationException("用户名与密码不匹配!");
}
AuthenticationInfo authent = new SimpleAuthenticationInfo(token.getPrincipal() , token.getCredentials() , this.getName());
return authent;
}
}
点赞
发表评论
当前回复:作者