2019独角兽企业重金招聘Python工程师标准>>>
我们要加入组织机构进行登录,无非就是多传递一个参数给shiro,之后在自己的realm里面进行验证,所以问题的关键是要如何获取这个组织机构,查看一下shiro,发现shiro是通过FormAuthenticationFilter,UsernamePasswordToken来进行用户名密码的传递的,感兴趣的朋友可以详细读一下源码。
所以对这两个类进行扩展,代码如下:
FormAuthenticationFilter:
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
public class MyFormAuthenticationFilter extends FormAuthenticationFilter{
private String orgcodeParam="orgcode";
public String getOrgcodeParam() {
return orgcodeParam;
}
protected String getOrgcode(ServletRequest request) {
return WebUtils.getCleanParam(request, getOrgcodeParam());
}
@Override
protected AuthenticationToken createToken(ServletRequest request,
ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
String orgcode = getOrgcode(request);
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
return new MyUsernamePasswordToken(username, password, rememberMe,
host, orgcode);
}
}
UsernamePasswordToken:
import org.apache.shiro.authc.UsernamePasswordToken;
public class MyUsernamePasswordToken extends UsernamePasswordToken{
/**
*
*/
private static final long serialVersionUID = 1L;
private String orgcode;
public MyUsernamePasswordToken (){}
public MyUsernamePasswordToken (String username, String password,
boolean rememberMe, String host, String orgcode) {
super(username, password, rememberMe, host);
this.orgcode = orgcode;
}
public String getOrgcode() {
return orgcode;
}
public void setOrgcode(String orgcode) {
this.orgcode = orgcode;
}
}
ok写完这两个类,工作基本上就完成大部分了,接下来在登录页面加入组织机构的组件,name属性要和MyFormAuthenticationFilter类中的常量 private String orgcodeParam="orgcode";保持一致。
然后更改shiro配置文件中的过滤器,改成MyFormAuthenticationFilter,简单的做法就是在配置文件中搜索FormAuthenticationFilter然后替换成MyFormAuthenticationFilter即可。
最后改写MyRealm中的doGetAuthenticationInfo方法,“MyRealm”是我们实现登录以及授权认证的AuthorizingRealm的子类,代码如下,其实就是吧原来的UsernamePasswordToken改成MyUsernamePasswordToken
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken ) throws AuthenticationException {
MyUsernamePasswordToken token = (MyUsernamePasswordToken) authcToken;
String userName = token.getUsername();
String passWord = String.valueOf(token.getPassword());
String orgCode = String.valueOf(token.getOrgcode());
System.out.println("\n****************orgCode:"+orgCode+"************\n");
System.out.println("\n****************userName:"+userName+"************\n");
if( userName != null && !"".equals(userName) ){
UserInfoExample example = new UserInfoExample();
// md5加密
try {
passWord = new String(passWord);
MessageDigest md = MessageDigest.getInstance("MD5");
// md.digest() 该函数返回值为存放哈希值结果的byte数组
passWord = byteToString(md.digest(passWord.getBytes()));
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
example.createCriteria().andUsernameEqualTo(userName).andUserpassEqualTo(passWord);
List<UserInfo> users = userInfoMapper.selectByExample(example);
UserInfo user = null;
if(users != null && users.size() > 0) {
user = users.get(0);
}
if( user != null ) {
//设置当前用户
token.setPassword(passWord.toCharArray());
SecurityUtils.getSubject().getSession().setAttribute("userId", user.getUserid());
SecurityUtils.getSubject().getSession().setAttribute("userName", user.getUsername());
return new SimpleAuthenticationInfo(
user.getUsername(),user.getUserpass(), getName());
}
}
return null;
}
到此我们就完成了shiro基于组织机构的登录认证,运行程序看如下效果