shiro的入门级使用(纯java应用)
1. 创建一个新的java应用(maven)
在pom文件中引入如下依赖:
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <!-- 日志工具 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.2</version> </dependency> <!-- shiro默认需要的日志工具,不添加时shiro运行失败 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>
工程结构如下图:
2. 通过配置文件的方式使用shiro
(1)在resources文件夹下新增TestShiro.ini配置文件,内容如下:
#[main] myRealm = com.ynsh.security.shiro.DatabaseRealm credentialsMatcher = com.ynsh.security.shiro.MyCredentialsMatcher myRealm.credentialsMatcher = $credentialsMatcher securityManager.realms = $myRealm securityManager.sessionManager.globalSessionTimeout = 1800000 [users] javass = cc,role1 [roles] role1 = p1,p2
(2)创建自定义的realm
package com.ynsh.security.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import java.util.HashSet;
import java.util.Set;
public class DatabaseRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String userName = (String)getAvailablePrincipal(principalCollection);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Set<String> s = new HashSet<>();
s.add("p1");
info.setStringPermissions(s); //赋予权限p1
Set<String> r = new HashSet<>();
r.add("role1"); //赋予角色role1
info.setRoles(r);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
String userName = (String)upToken.getPrincipal();
// if ("javass".equals(userName)) throw new AuthenticationException("javass用户禁止登录"); 如果想禁止某一个用户登录,可以在这里操作:判断到是这个用户时,扔出异常
//这个密码正常情况下应该是从数据库去获取
String passWord = "428729c9b80aa3198300caabb24f8a88";
//扔给credentialsMatcher去判断
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
userName, passWord, null, this.getName());
return simpleAuthenticationInfo;
}
//父类调用完doGetAuthenticationInfo会调用assertCredentialsMatch,判断密码是否相符
}(3)创建自定义的credentialsMatcher,即密码验证器
package com.ynsh.security.shiro;
import com.ynsh.security.utils.Md5Util;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
public class MyCredentialsMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken uToken = (UsernamePasswordToken)token;
String inPassword = new String(uToken.getPassword()); //这个密码是客户提交的密码,即下面main函数中用new UsernamePasswordToken("javass","bb")提交的“bb”
//这个密码是上面realm中给出的数据库密码,也就是正确的密码:String passWord = "428729c9b80aa3198300caabb24f8a88"
String dbPassword = (String)info.getCredentials();
String encryptInPassword = Md5Util.encrypt(inPassword);
return encryptInPassword.equals(dbPassword);
}
}(4)上面用到了一个自定义的md5Util组件:
package com.ynsh.security.utils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
public class Md5Util {
public static String encrypt(String originalString){
//盐
String salt = "salt";
//散列次数
int hashIterations = 2;
Md5Hash md5Hash = new Md5Hash(originalString, salt, hashIterations);
String password_md5 = md5Hash.toString();
System.out.println(password_md5);
//第一个参数:散列算法
SimpleHash simpleHash = new SimpleHash("md5", originalString, salt, hashIterations);
System.out.println(simpleHash.toString());
return simpleHash.toString();
}
}(5)正式开始验证,写main函数:
package com.ynsh;
import org.apache.shiro.SecurityUtils;
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;
public class App
{
private static final Logger logger = LoggerFactory.getLogger(App.class);
public static void main( String[] args )
{
Factory<SecurityManager> f = new IniSecurityManagerFactory("classpath:TestShiro.ini");
SecurityManager s = f.getInstance();
SecurityUtils.setSecurityManager(s);
UsernamePasswordToken token = new UsernamePasswordToken("javass","bb");
token.setRememberMe(true);
Subject currentUser = SecurityUtils.getSubject();
try {
currentUser.login(token);
}catch (Exception e){
logger.error(e.getMessage());
e.printStackTrace();
}
// boolean flag = currentUser.isPermitted("p1");
boolean flag = currentUser.isAuthenticated();
System.out.println("flag == "+flag);
flag = currentUser.hasRole("role1");
logger.info("用户有角色:{}",flag);
}
}(6)运行结果如下:
[INFO ] 2018-11-22 15:13:43,087 method:org.apache.shiro.config.IniSecurityManagerFactory.isAutoApplyRealms(IniSecurityManagerFactory.java:127) Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur. 428729c9b80aa3198300caabb24f8a88 428729c9b80aa3198300caabb24f8a88 [INFO ] 2018-11-22 15:13:43,102 method:org.apache.shiro.session.mgt.AbstractValidatingSessionManager.enableSessionValidation(AbstractValidatingSessionManager.java:233) Enabling session validation scheduler... flag == true [INFO ] 2018-11-22 15:13:43,147 method:com.ynsh.App.main(App.java:43) 用户有角色:true Process finished with exit code 0
后记
TestShiro.ini中配置了[users]和[roles]其实是不起作用的,这个配置是一开始的时候为了验证shiro默认的iniRealm的时候使用的。
因为自定义了realm,可以将[users]和[roles]的内容全部删除。
相关推荐
xclxcl 2020-08-03
zmzmmf 2020-08-03
likesyour 2020-08-01
杜鲁门 2020-11-05
luckyxl0 2020-08-16
Dullonjiang 2020-08-09
MicroBoy 2020-08-02
ganjing 2020-08-02
zmzmmf 2020-07-09
MicroBoy 2020-07-05
zzhao 2020-06-26
子云 2020-06-18
visionzheng 2020-06-07
neweastsun 2020-06-04
ErixHao 2020-06-03
GDreams0 2020-06-01
ganjing 2020-05-29
zmzmmf 2020-05-28
nullcy 2020-05-26