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