先说说项目中的实际需求。首先项目是有shiro的,也有一套完整的登录认证系统,能够实现使用缓存/dao进行登录用户名密码的校验。然后最近有一个需求,需要实现手机端的登录,登录的请求链接与web端不同,验证是由另外一台服务器进行验证的,使用webservice进行通信。

总结一下,也就是说需要实现一套使用WebService的登录接口。

我使用的解决方案是开放一个无需验证的登录接口给app端使用,在这个接口中调用登录的方法,并且使用webService去进行用户名密码的校验。

1、修改配置文件

在shiro的配置文件中,增加无需验证的登录接口

<bean name="shiroFilterChainDefinitions" class="java.lang.String">   <constructor-arg>      <value>         ${adminPath}/app/user/login = anon         ${adminPath}/app/user/notAuthorized = user         ${adminPath}/app/user/sessionTimeout = anon

      </value>   </constructor-arg></bean>

2、自定义的Token

/*** 自定义的移动端登录token,因为用户名和密码不需要本系统进行校验,所以只需要保存是否校验通过和校验通过后的用户id*/
public class AppToken extends AuthenticationToken {private static final long serialVersionUID = 8587329689973009518L;private String checked = null;  //webService的校验是否通过private String userId = null;   //登录用户的idprivate boolean isRememberMe = false;   //是否勾选记住我public AppToken(String userId, String ticket) {this.userId = userId;this.checked = ticket;}/*** 获取当前token的身份,即用户id* @return*/public Object getPrincipal() {return this.userId;}/*** 获取当前用户的凭证,即是否认证通过* @return*/public Object getCredentials() {return this.checked;}public void setUserId(String userId) {this.userId = userId;}public boolean isRememberMe() {return this.isRememberMe;}public void setRememberMe(boolean isRememberMe) {this.isRememberMe = isRememberMe;}
}

3、自定义的Realm,并且加入到配置文件中的配置中去

/*** 自定义的移动端认证器,并不进行任何的认证工作,只是为当前用户处理session*/
@Service
public class AppRealm extends AbstractCustomRealm {private SystemService systemService;private SystemAuthorizingRealm realm;private String name;private Logger logger = Logger.getLogger(getClass());@Overridepublic String getName() {return this.name;}@Overridepublic boolean supports(AuthenticationToken authenticationToken) {return authenticationToken!=null;}@Overridepublic AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {if (! (authenticationToken instanceof AppToken)) return null;//只有通过app登录接口进来的请求才能使用该认证器AppToken token = (AppToken)authenticationToken;Object principal = token.getPrincipal();    //获取token中的身份,是用户的idUser user = getSystemService().getUser((String) principal);//从系统缓存中获取当前用户的信息SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(new SystemAuthorizingRealm.Principal(user, false),token.getCredentials(),user.getLoginName());//创建Info对象,并不进行校验return authenticationInfo;}

  

@Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return getRealm().doGetAuthorizationInfo(principalCollection); } private SystemService getSystemService() { if (systemService == null){ systemService = SpringContextHolder.getBean(SystemService.class); } return systemService; } private SystemAuthorizingRealm getRealm() { if(realm == null){ realm = SpringContextHolder.getBean(SystemAuthorizingRealm.class); } return realm; }

加入配置文件

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realms"><list><ref bean = "appRealm"/><ref bean = "systemAuthorizingRealm"/></list></property><property name="sessionManager" ref="sessionManager" /><property name="cacheManager" ref="shiroCacheManager" /><property name="authenticator" ref="authenticator"/></bean>

4、完成接口,在接口中对用户名和密码进行处理

@Controller
@RequestMapping(value = "${adminPath}/" + AppConst.AppUser_Action)
public class AppUserController extends BaseController {@Autowiredprivate SystemService systemService;
private String oaWsUrl = "test"@ResponseBody@RequestMapping(value = "login")public String login(UserLoginVo loginVo) {    Result res = new Result();try {AppToken phoneToken = null;boolean app = false;User user = null;String result = UserAuthWsClient.authUserOAWS(loginVo.getUsername(), loginVo.getPassword(), oaWsUrl);String[] results = result.split("-");if (!"0".equals(results[0])){if (results.length > 1) {logger.error(results[1]);}logger.debug("移动端登录(userid: "+loginVo.getUsername()+")登录失败.");res.setMessage("用户名或者密码错误,请重新输入");res.setCode(ResponseVo.FAIL);return res;}if ("0".equals(results[0])) {String JC = loginVo.getUsername() ;user = UserUtils.get(JC);if (user != null) {if (user.getDelFlag() == 0) {app = true;}}if(app){phoneToken = new AppToken(user.getId(), "checked");}}if(!app){//本系统中没有该用户,判断登录失败res.setMessage("登录失败, 请联系管理员");res.setCode(ResponseVo.FAIL);}else{Subject subject = SecurityUtils.getSubject();try {UserUtils.clearCache();subject.login(phoneToken);logger.debug("移动端登录(userid: "+user.getId()+") 登录成功,");res.setMessage("登陆成功");res.setBody(loginVo);res.setCode(ResponseVo.SUCCESS);} catch (AuthenticationException e) {logger.debug("移动端登录(userid: "+user.getId()+")登录失败.");logger.error(e.getMessage(),e);res.setMessage("用户名或者密码错误,请重新输入");res.setCode(ResponseVo.FAIL);}return res;}}    }  }}

总结一下,因为用户名和密码的校验不在本系统内完成,所以对用户名和密码就不需要传入到shiro相关的流程中,直接使用继承自CachingRealm的自定义认证器AbstractCustomRealm ,在这里面不会对token和info的一致性进行校验,因此就不需要关心账号和密码了。

如果是自定的Realm继承自 AuthorizingRealm,那么AuthorizingRealm还会对token和info的一致性进行校验,只有当校验成功后才算是登录成功,否则抛出异常登录失败

转载于:https://www.cnblogs.com/pengjian-one/p/7428055.html

shiro使用WebService进行验证的实现相关推荐

  1. WebService简单验证:SoapHeader

    使用soaphead方法可以在webservice的请求中增加头部信息,当有人调用我们的webservice时,可以通过查询这个请求的头部信息并验证来防止该软件以外的程序调用webservice us ...

  2. JAX-WS使用Handler实现简单的WebService权限验证

    WebService如果涉及到安全保密或者使用权限的时候,WS-Security通常是最优选择.WS-Security (Web服务安全) 包含了关于如何在WebService消息上保证完整性和机密性 ...

  3. java webservice用户验证_使用java webservice的.net4.0 web app需要Usernametoken身份验证

    我是使用.net 4.0 VS2010的新手.我需要使用java web服务并发送usernametoken自定义身份验证来访问服务,这是我很容易在VS2005中使用WSE2.0,那么在net 4.0 ...

  4. java webservice 身份验证_java-Http基本身份验证不适用于Spring WS和WebS...

    我尝试使用Spring(-WS)将HTTP基本身份验证凭据添加到我的SOAP请求中.该请求本身有效,但是没有凭据提交. HTTP标头应如下所示: [...] Connection: Keep-Aliv ...

  5. Shiro系列-Shiro如何实现身份验证

    导语   下面就来按照顺序依次介绍一下Shiro的使用场景,场景代码后续会放到GitHub上面希望大家可以多多支持.首先先来介绍一下Shiro的身份认证. 文章目录 Shiro身份验证 入门小例子 环 ...

  6. Shiro的多Realm验证的实现--shiro实现不同身份使用不同Realm进行验证

    如果要看多Realm进行授权: 请参看   https://blog.csdn.net/u013294097/article/details/90066869 假设现在有这样一种需求:存在两张表use ...

  7. java webservice用户验证_java webservice 用户验证 (服务端 + 客户端)

    说明:在网上找了一堆 handler验证的东东,试验了一下,没成功. 现在换了一种方式:在 tomcat的配置文件中添加用户角色和用户信息 然后在 webservice的项目配置文件中增加对应的角色. ...

  8. 使用shiro进行系统身份验证-权限控制,登录界面乱跳

    问题描述;shiro验证成功后,跳转页面不是shiro.xml文件中配置的跳转地址 1.自定义MyFormAuthenticationFilter继承FormAuthenticationFilter并 ...

  9. shiro cas 遇到 票根验证问题

    1.票根不符合目标服务 解决方法:检查web.xml里的shiro拦截器和cas ticket拦截器的拜访顺序,应该cas 白在shiro前面 原因:shiro也有验证机制,但不识别票根. 2.票根无 ...

最新文章

  1. java.lang.SecurityException Permission Denial opening provider ngyb.createdatabase.AccountProvider
  2. 动态给组件添加背景,一半圆角
  3. Nexus搭建Maven私有仓库
  4. 一个人成长最快速的方法
  5. SCI科技论文写作、投稿与发表(一)
  6. 23. 线程如何退出结束
  7. 《知乎周刊:读书这件小事》摘记及书评
  8. 计算机操作系统——程序执行的流程
  9. 橘子学设计模式之原型模式
  10. python判断手机号运营商_python手机号码运营商归属测试
  11. Hierarchical Z-Buffer Visibility (Hi-Z)
  12. leetcode第643题C++
  13. 什么是固态硬盘?它有什么好处?
  14. 科研—画图图片处理1
  15. matlab访问被拒绝,安装MATLAB拒绝访问问题的解决方法
  16. 春节假期顺延30天!网友:酸了!员工不乐意了……
  17. linux 性能测试 antutu,安兔兔“不诚实”?这三款跑分软件绝对值得一试!
  18. flexslider图片轮播
  19. What Types of Movies Do You like ?
  20. 价值观、本能和内驱力

热门文章

  1. 编程语言和shell编程的基础内容以及grep、egrep命令及相应的正则表达式和用法...
  2. oracle v$sysstat性能视图
  3. 优秀的互联网项目经理/市场总监如何选择给力的互联网技术实现团队?
  4. centOS中网络配置相关文件配置选项说明
  5. 梦幻群侠传5帮派修炼_梦幻封妖传5门派技能介绍 | 手游网游页游攻略大全
  6. Java中获取文件大小的正确方法
  7. MatrixCursor 模拟数据库
  8. Android两次按返回键退出应用程序
  9. 2013年度【博客之星评选活动】正在进行中,希望大家支持下,十分感谢!
  10. androidpn的学习研究(四)androidpn-client客户端几个类说明