shiro自定义Realm(数据源)
Posted bigbigxiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro自定义Realm(数据源)相关的知识,希望对你有一定的参考价值。
2.1一样先导包
<!--使用shiro需要先导包--> <dependencies> <!--shiro的核心包--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <!--日志包--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!--测试包--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> </dependency> </dependencies>
2.2准备自定义Realm
- 写一个Realm,继承
AuthorizingRealm
- 提供了两个方法,一个是授权
doGetAuthorizationInfo
,一个是身份认证doGetAuthenticationInfo
(准备个MyRealm.java文件,填写如下内容 )
public class MyRealm extends AuthorizingRealm { //授权认证功能就写在这里面 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取授权对象 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //从getRoles()方法中获取角色并放且放到授权对象中,getRoles()方法在下面 Set<String> roles = getRoles(); authorizationInfo.setRoles(roles); //从getPerms()方法中获取权限并放且放到授权对象中,getPerms()方法在下面 Set<String> perms = getPerms(); authorizationInfo.setStringPermissions(perms); return authorizationInfo; } /** * 假设这里获取到当前用户的角色 */ private Set<String> getRoles(){ Set<String> roles = new HashSet<>(); roles.add("admin"); roles.add("it"); return roles; } /** * 假设这里获取到当前用户的权限 */ private Set<String> getPerms(){ Set<String> perms = new HashSet<>(); perms.add("employee:index"); return perms; } /** * 记住:如果这个方法返回null,就代表是用户名错误,shiro就会抛出:UnknownAccountException */ //身份认证(登录)就写在这里面 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //1.拿到令牌(UsernamePasswordToken) UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; //2.拿到用户名,判断这个用户是否存在 // 2.1 拿到传过来的用户名 String username = token.getUsername(); // 2.2 根据用户名从getUsers()方法中拿到密码,getUsers()方法在下面 String password = this.getUsers(username); // 2.3 如果没有拿到密码(没有通过用户名拿到相应的用户->用户不存在) if(password==null){ return null; } //记住:我们只在正常完成这里的功能,shiro会判断密码是否正确 //3.返回 AuthenticationInfo这个对象 /** * 咱们创建对象需要传的参数:SimpleAuthenticatinInof(4个参数顺序解释) * Object principal:主体(可以乱写) -> 登录成功后,你想把哪一个对象存下来 * Object credentials:凭证(就是密码) -> 数据库中的密码 * credentials(密码)Salt:盐值 * String realmName : realm的名称(可以乱写) */ //拿到咱们的盐值对象(ByteSource) ByteSource salt = ByteSource.Util.bytes("itsource"); SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,"myRealm"); return authenticationInfo; } /** * 假设这里是根据用户名进行的查询 * MD5:e10adc3949ba59abbe56e057f20f883e * MD5+10次:4a95737b032e98a50c056c41f2fa9ec6 * MD5+10次+itsource:831d092d59f6e305ebcfa77e05135eac */ public String getUsers(String username){ if("admin".equals(username)){ return "831d092d59f6e305ebcfa77e05135eac"; }else if("zhang".equals(username)){ return "123"; } return null; } }
2.3测试自定义Realm(一定得有import org.junit.Test;才能测试)
@Test public void testMyRealm() throws Exception{ //一.创建一个SecurityManager对象 // 1.创建realm对象 MyRealm myRealm = new MyRealm(); // 2.创建SecurityManager对象 DefaultSecurityManager securityManager = new DefaultSecurityManager(myRealm); //②.相当于把SecurityManager放到了当前上下文 SecurityUtils.setSecurityManager(securityManager); //③.拿到当前用户 Subject subject = SecurityUtils.getSubject(); //Hashed(哈希)Credentials(认证)Matcher(匹配器) HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //设置哈希算法 matcher.setHashAlgorithmName("MD5"); //设置迭代次数 matcher.setHashIterations(10); //把匹配器交给shiro myRealm.setCredentialsMatcher(matcher); System.out.println("用户是否登录:"+subject.isAuthenticated()); //④.如果没有登录,让他登录 if(!subject.isAuthenticated()){ try { UsernamePasswordToken token = new UsernamePasswordToken("admin","123456"); subject.login(token); } catch (UnknownAccountException e) { e.printStackTrace(); System.out.println("用户名错误"); } catch (IncorrectCredentialsException e) { e.printStackTrace(); System.out.println("密码错误"); } catch (AuthenticationException e) { e.printStackTrace(); System.out.println("神迷错误"); } } System.out.println("用户是否登录:"+subject.isAuthenticated()); System.out.println("是否是admin角色:"+subject.hasRole("admin")); System.out.println("是否是hr角色:"+subject.hasRole("hr")); System.out.println("是否有employee:index权限:"+subject.isPermitted("employee:index")); System.out.println("是否有employee:save权限:"+subject.isPermitted("employee:save")); System.out.println("是否有department:index权限:"+subject.isPermitted("department:index")); }
以上是关于shiro自定义Realm(数据源)的主要内容,如果未能解决你的问题,请参考以下文章