您的位置:首页 > 其它

使用shiro进行登录校验;自定义realm的实现

2016-06-05 15:49 531 查看
在web中, 用户输入用户名密码登录,我们需要用这些信息和已经注册存在在数据库中的账户信息进行对比,判断用户名和密码是否正确。

shiro提供了自定义realm的实现来进行处理对不同数据源的校验:

realm就是一个安全数据源。可以将其看作为数据库的另一层封装,连接了应用和db

用户提交的数据流到reaml中,reaml中存着数据库中的账户信息,因此进行对比。

1、首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必

须通过SecurityUtils. setSecurityManager()设置;

2、SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;

3、Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自

定义插入自己的实现;

4、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认

ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;

5、Authenticator 会把相应的token 传入Realm,从Realm 获取身份验证信息,如果没有返

回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进

行访问。

自定义realm的实现:在获取securityManager的时候初始化指定了ini配置文件,配置文件中指定让shiro执行自定义的realm,而不是

最初的[users]的这种方式来获取用户名和密码:

自定义realm时候配置文件的写法: realm名称=realm实现类的全路径,shiro反射拿到 ,设置securityManager.realms=$自定义reaml名

多个reaml实现的时候,继续往下追加

类似:

realm1=.......

realm2=.......

realm3=.......

securityManager.realms=$realm1,$realm2,$realm3

#声明一个realm
myRealm1= com.gjj.test.shiro.RealmService
#指定securityManager的realms实现,通过$name来指定realm
securityManager.realms=$myRealm1


shiro的实现:

1.实现Realm接口:

package com.gjj.test.shiro;

import org.apache.shiro.authc.*;
import org.apache.shiro.realm.Realm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 自定义realm的实现
* Created by guojiangjiang on 2016/6/5.
*/
public class RealmService implements Realm {
private static final Logger logger = LoggerFactory.getLogger(RealmService.class);
private static final String REAM_NAME = "OwnRealm";
/**
* 返回一个唯一的realm名字
*
* @return
*/
@Override
public String getName() {
return this.REAM_NAME;
}

/**
* 判断此realm是否支持此token
*
* @param authenticationToken
* @return
*/
@Override
public boolean supports(AuthenticationToken authenticationToken) {
//是否支持用户名登录的token
return authenticationToken instanceof UsernamePasswordToken;
}

/**
* 根据token获取认证信息
*
* @param token 认证令牌
* @return
* @throws AuthenticationException
*/
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

String userName = String.valueOf(token.getPrincipal());
String passwd = String.valueOf(token.getCredentials());
int count = 0;
if ("jack".equals(userName)) {
count += 1;
logger.info("用户名正确:{}", userName);
} else {
throw new UnknownAccountException("用户名错误!");
}
if ("12345".equals(passwd)) {
count += 1;
logger.info("密码正确:{}", passwd);
} else {
throw new IncorrectCredentialsException("密码错误!!!");
}
//        返回认证信息的一个简单实现,三个参数,用户名,密码,域name
AuthenticationInfo info = new SimpleAuthenticationInfo(userName, passwd, this.REAM_NAME);

return info;
}
}
2.配置 shiro_realm.ini

#声明一个realm
myRealm1= com.gjj.test.shiro.RealmService
#指定securityManager的realms实现,通过$name来指定realm
securityManager.realms=$myRealm1


3.在代码中接收用户提交的参数,配置realm:

package com.gjj.test.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.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Realm:域,Shiro 从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager
* 要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;
* 也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看
* 成DataSource , 即安全数据源。如我们之前的ini 配置方式将使用
* org.apache.shiro.realm.text.IniRealm。
* realm就类似于安全数据源。
* <p/>
* Created by guojiangjiang on 2016/6/5.
*/
public class RealmTest {
private static final Logger logger = LoggerFactory.getLogger(RealmTest.class);

public static void main(String[] args) {
testRealm();
}

private static void testRealm() {
//1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro_ownRealm.ini");
//2、得到SecurityManager实例并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("jack", "12345");
try {
//4、登录,即身份验证
subject.login(token);
} catch (AuthenticationException e) {
//5、身份验证失败
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: