关于 项目中用到shiro如何通过token鉴权登录,模拟登录,代码直接登录的问题!
2015-09-10 20:52
1126 查看
1.今天遇到了一个棘手的问题,在此写下博客记录下来,用于提醒自己,以及帮助以后会遇到这样的问题的人
shiro框架中如何通过用户名密码在代码中直接登录?
首先在网上找了下,找到了这种方式:
由于自己的项目中登录时还要判断用户角色所以,用了UsernamePasswordUsertypeToken.java,代码如下
这里controller层里的代码差不多了,接下来要修改shiro里的配置以及Realm
配置如下:
com.linkage.educloud.ucenter.learn.service.ShiroAndEduRealm.java代码如下:
这下可终于解决了用户直接通过token鉴权登录的问题了。
例子:
shiro框架中如何通过用户名密码在代码中直接登录?
首先在网上找了下,找到了这种方式:
Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username,password, false,request.getRemoteAddr()); currentUser.login(token);
由于自己的项目中登录时还要判断用户角色所以,用了UsernamePasswordUsertypeToken.java,代码如下
package com.linkage.educloud.ucenter.login.shiro; import org.apache.shiro.authc.HostAuthenticationToken; import org.apache.shiro.authc.RememberMeAuthenticationToken; /** * 参考org.apache.shiro.authcUsernamePasswordToken,增加了用户类型参数 * @author caihz * @see org.apache.shiro.authcUsernamePasswordToken */ public class UsernamePasswordUsertypeToken implements HostAuthenticationToken, RememberMeAuthenticationToken { /** * 用户名 */ private String username; /** * 密码, in char[] format */ private char[] password; /** * 是否记住我 * 默认值:<code>false</code> */ private boolean rememberMe = false; /** * 主机名称或ip */ private String host; /** * 用户类型 */ private String usertype; public UsernamePasswordUsertypeToken() { } /** * 构造方法 * @param username 用户名 * @param password 密码(char[]) * @param rememberMe 是否记住我 * @param host 主机或ip * @param usertype 用户类型 */ public UsernamePasswordUsertypeToken(final String username, final char[] password, final boolean rememberMe, final String host, final String usertype) { this.username = username; this.password = password; this.rememberMe = rememberMe; this.host = host; this.usertype = usertype; } /** * 构造方法 * @param username 用户名 * @param password 密码(String) * @param rememberMe 是否记住我 * @param host 主机或ip * @param usertype 用户类型 */ public UsernamePasswordUsertypeToken(final String username, final String password, final boolean rememberMe, final String host, final String usertype) { this(username, password != null ? password.toCharArray() : null, rememberMe, host, usertype); } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public char[] getPassword() { return password; } public void setPassword(char[] password) { this.password = password; } /** * Simply returns {@link #getUsername() getUsername()}. * * @return the {@link #getUsername() username}. * @see org.apache.shiro.authc.AuthenticationToken#getPrincipal() */ public Object getPrincipal() { return getUsername(); } /** * Returns the {@link #getPassword() password} char array. * * @return the {@link #getPassword() password} char array. * @see org.apache.shiro.authc.AuthenticationToken#getCredentials() */ public Object getCredentials() { return getPassword(); } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public boolean isRememberMe() { return rememberMe; } public void setRememberMe(boolean rememberMe) { this.rememberMe = rememberMe; } public String getUsertype() { return usertype; } public void setUsertype(String usertype) { this.usertype = usertype; } /** * 清除数据 * 密码如果不为空,设置成0x00 */ public void clear() { this.username = null; this.host = null; this.rememberMe = false; this.usertype = null; if (this.password != null) { for (int i = 0; i < password.length; i++) { this.password[i] = 0x00; } this.password = null; } } /** * 重写toString方法 */ public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getName()); sb.append(" - "); sb.append(username); sb.append(", usertype=").append(usertype); sb.append(", rememberMe=").append(rememberMe); if (host != null) { sb.append(" (").append(host).append(")"); } return sb.toString(); } }将上述代码修改了下,如下:
Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordUsertypeToken token = new UsernamePasswordUsertypeToken(user.getPhone(),user.getLoginPass(), false,req.getRemoteAddr(),role); currentUser.login(token);
这里controller层里的代码差不多了,接下来要修改shiro里的配置以及Realm
配置如下:
<!-- 和教育的Realm 2015-9-10--> <bean id="shiroAndEduRealm" class="com.linkage.educloud.ucenter.learn.service.ShiroAndEduRealm"> <!-- property name="accountService" ref="accountService"/ --> <!-- 获得的用户密码已经是加密过的了,验证的时候不用加密验证了--> <!-- <property name="credentialsMatcher" ref="credentialsMatcher"/> --> <property name="authenticationTokenClass" value="com.linkage.educloud.ucenter.login.shiro.UsernamePasswordUsertypeToken"/> </bean>
<bean id="authenticator" class="com.linkage.educloud.ucenter.login.shiro.FirstSuccessfulModularRealmAuthenticator"> <property name="authenticationStrategy" ref="firstSuccessfulStrategy"/> <property name="realms"> <list> <ref bean="shiroDbRealm"/> <ref bean="shiroXxtRealm"/> <ref bean="shiroAndEduRealm"/> </list> </property> </bean>
com.linkage.educloud.ucenter.learn.service.ShiroAndEduRealm.java代码如下:
package com.linkage.educloud.ucenter.learn.service; import org.apache.shiro.authc.AccountException; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import com.linkage.educloud.api.ucenter.service.Uc2XXTIfaceService; import com.linkage.educloud.base.util.StringUtil; import com.linkage.educloud.domain.ucenter.login.UcenterLoginUser; import com.linkage.educloud.ucenter.login.service.UcenterLoginService; import com.linkage.educloud.ucenter.login.shiro.UsernamePasswordUsertypeToken; /** * 校讯通的登录Realm * @author caihz * */ public class ShiroAndEduRealm extends AuthorizingRealm { final static Logger log = LoggerFactory.getLogger(ShiroAndEduRealm.class); @Autowired private UcenterLoginService ucenterLoginService; @Autowired private Uc2XXTIfaceService xxtService; /** * 登录认证回调函数,登录时调用. * @param authcToken 登录页面参数,用户名和密码等 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordUsertypeToken token = (UsernamePasswordUsertypeToken) authcToken; String username = token.getUsername(); if (username == null){ throw new AccountException("账号不能为空"); } //如果用户中心没有用户,则请求校讯通登录接口并查询用户中心对应的用户 String password = String.valueOf(token.getPassword()); //password = StringUtil.md5(password); password = password.toLowerCase(); UcenterLoginUser user = ucenterLoginService.findUserByXxt(token.getUsername(), password, token.getUsertype()); if (user != null){ return new SimpleAuthenticationInfo(user, user.getLoginPass(), getName()); }else { return null; } } /** * 登录认证通过后的权限查询函数, 由于目前用户中心前台页面不需要权限控制,所以没写,以后如果需要可扩展 * * @see org.apache.shiro.authz.AuthorizationInfo */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); return info; } }
这下可终于解决了用户直接通过token鉴权登录的问题了。
例子:
@RequestMapping("/test") public String test(HttpServletRequest request){ Subject subject = SecurityUtils.getSubject(); // subject.login(new UsernamePasswordToken(user.getPhone(), user.getLoginPass())); //UsernamePasswordUsertypeToken up = new UsernamePasswordUsertypeToken("13816005001", "123456aA1", false, null, "3"); UsernamePasswordUsertypeToken up = new UsernamePasswordUsertypeToken("20212414", "4d45acd6c95faab86980ebbae7cad57c", false, request.getRemoteAddr(), "1"); //UsernamePasswordUsertypeToken up = new UsernamePasswordUsertypeToken("20212414", "bLaP7@3U", false, request.getRemoteAddr(), "1"); subject.login(up); System.out.println("家长登录成功!"); return "redirect:/ucenter/index/index"; }
相关文章推荐
- 【C++学习笔记】-static的用法
- python unittest 深入failfast及实际应用【示例】
- C语言学习之基本类型在内存中的大小
- springDi
- C#的委托
- 揭开Socket编程的面纱
- 编写高性能的Lua代码
- spring带来的春天
- Python经常使用第三方工具、库、骨架
- java 知识
- 赛码在线编程1001
- Spring Framework 下载链接_现在有空
- C++数据类型总结
- 项目1-c/c++语言中函数参数传递的三种方式
- 赛码在线编程1000
- C++ string使用详解
- 【leetcode】Binary Tree Right Side View --C++
- Mac OSX OpenFire无法启动,配置Java运行时环境变量
- Mysql: Connect/C++ 使用过程中发现返回 std::string 造成的内存泄露
- C# WinForm开发系列 - 文章索引