@Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae, ServletRequest request, ServletResponse response) { final OAuthResponse oAuthResponse; try { oAuthResponse = OAuthRSResponse.errorResponse(401) .setError(OAuthError.ResourceResponse.INVALID_TOKEN) .setErrorDescription(ae.getMessage()) .buildJSONMessage(); com.monkeyk.os.web.WebUtils.writeOAuthJsonResponse((HttpServletResponse) response, oAuthResponse); } catch (OAuthSystemException e) { LOGGER.error("Build JSON message error", e); throw new IllegalStateException(e); } return false; }
/** * 认证回调函数,登录时调用. */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { UsernamePassword2Token token = (UsernamePassword2Token) authcToken; String username = token.getUsername(); if (username == null || null == username) { throw new AccountException( "Null usernames are not allowed by this realm."); } User entity = new User(); entity.setEmail(username); entity.setStatus(Constant.STATUS_ENABLED); entity = (User) service.iUserService.select(entity); if (null == entity) { throw new UnknownAccountException("No account found for user [" + username + "]"); } byte[] key = Encode.decodeHex(entity.getRandom()); return new SimpleAuthenticationInfo(new Shiro(entity.getId(), entity.getEmail(), entity.getName()), entity.getPassword(), ByteSource.Util.bytes(key), getName()); }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //UsernamePasswordToken对象用来存放提交的登录信息 UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken; log.info("验证当前Subject时获取到token为:" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE)); // return new SimpleAuthenticationInfo("hsjhsj","8e24137dee97c9bbddb9a0cd6e043be4" , getName()); return new SimpleAuthenticationInfo("hsjhsj","" , getName()); //查出是否有此用户 // TbUser user=null; // if(user!=null){ // 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验 // return new SimpleAuthenticationInfo(user.getUsername(), , getName()); // } // return null; }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { String token = (String) auth.getCredentials(); Cache<String, String> authCache = CacheController.getAuthCache(); if (! authCache.containsKey(token)) { // get user info from database int uid = JWTUtil.getUid(token); UserEntity userEntity = userService.getUserByUid(uid); authCache.put(token, String.valueOf(userEntity.getPassword())); } String secret = authCache.get(token); if (!JWTUtil.decode(token, secret)) { throw new AuthenticationException("Token invalid"); } return new SimpleAuthenticationInfo(token, token, "jwt_realm"); }
/** * 用户登录 * @param request * @param user * @param model * @return */ @RequestMapping(value = "/login",method = RequestMethod.POST) public String login(HttpServletRequest request, AdminUser user, Model model) { if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){ request.setAttribute("msg","用户名或者密码不能为空!"); return "login"; } Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(),user.getPassword()); try { subject.login(token); return "redirect:/initPage"; }catch (LockedAccountException lae) { token.clear(); request.setAttribute("msg", "用户已经被锁定不能登录,请与管理员联系!"); return "login"; } catch (AuthenticationException e) { token.clear(); request.setAttribute("msg", "用户或密码不正确!"); return "login"; } }
@Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setContentType("application/json;charset=utf-8"); try { //处理登录失败的异常 Throwable throwable = e.getCause() == null ? e : e.getCause(); R r = R.error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage()); String json = new Gson().toJson(r); httpResponse.getWriter().print(json); } catch (IOException e1) { } return false; }
/** * 用户认证-验证用户是否登录、用户名密码是否匹配 */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { logger.info(">>> 【用户认证】token = {}", token); String userName = (String)token.getPrincipal(); AdminUser user = getPrincipalService().getPrincipalObject(userName); if(user == null) { throw new UnknownAccountException("Unknown account: " + userName);//没找到帐号 } if(AdminUserStatusEnum.ADMIN_USER_STATUS_DISABLED.getStatusCode().equals(user.getStatus())) { throw new LockedAccountException("Account[" + userName + "] has been locked!"); //帐号锁定 } //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user.getUserName(), //用户名 user.getPassword(), //密码 ByteSource.Util.bytes(user.getPasswordSalt()),//salt getName() //realm name ); return authenticationInfo; }
@Test public void testHelloWorld() { //1、获取 SecurityManager 工厂,此处使用 Ini 配置文件初始化 SecurityManager Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); //2、得到 SecurityManager 实例 并绑定给 SecurityUtils SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //3、得到 Subject 及创建用户名/密码身份验证 Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("test", "234"); try { //4、登录,即身份验证 subject.login(token); } catch (AuthenticationException e) { //5、身份验证失败 } Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录 //6、退出 subject.logout(); }
@Override protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception { HttpServletRequest request = (HttpServletRequest) servletRequest; String token = jwtHelper.getToken(request); String username = jwtHelper.getUsernameFromToken(token); StatelessToken accessToken = new StatelessToken(username, token); try { getSubject(servletRequest, servletResponse).login(accessToken); } catch (AuthenticationException e) { HttpServletResponse response = (HttpServletResponse) servletResponse; response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); objectMapper.writeValue(response.getWriter(), Result.fail(ResultCode.UNAUTHORIZED)); return false; } getSubject(servletRequest, servletResponse).isPermitted(request.getRequestURI()); return true; }
@Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae, ServletRequest request, ServletResponse response) { // OAuth2Token oAuth2Token = (OAuth2Token) token; final OAuthResponse oAuthResponse; try { oAuthResponse = OAuthRSResponse.errorResponse(401) .setError(OAuthError.ResourceResponse.INVALID_TOKEN) .setErrorDescription(ae.getMessage()) .buildJSONMessage(); com.monkeyk.os.web.WebUtils.writeOAuthJsonResponse((HttpServletResponse) response, oAuthResponse); } catch (OAuthSystemException e) { logger.error("Build JSON message error", e); throw new IllegalStateException(e); } return false; }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // identify account to log to UsernamePasswordToken userPassToken = (UsernamePasswordToken) token; final String username = userPassToken.getUsername(); if (username == null) { return null; } // read password hash and salt from db final User user = UserDAO.getUser(username); if (user == null) { return null; } // return salted credentials SaltedAuthenticationInfo info = new SaltedAuthInfo(username, user.getPassword(), user.getSalt()); return info; }
@PostMapping(value = SUBPATH_LOGIN) public ResponseEntity<UserDto> login(@RequestBody UserDto userDto, UriComponentsBuilder uriComponentsBuilder){ HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,SUBPATH_LOGIN); logger.info("================userInfo================username: " + userDto.getUsername() + ",pw: " + userDto.getPassword()); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(userDto.getUsername(),userDto.getPassword()); //User user = new User("root","root","root","root"); //userDao.save(user); try{ subject.login(token); } catch (AuthenticationException e){ logger.error("======登录失败======"); throw new ResultException(ErrorCode.USERNAMEORPASSWORD.getDesc(),ErrorCode.USERNAMEORPASSWORD); } UserDto loginUserDto = (UserDto) SecurityUtils.getSubject().getSession().getAttribute("user"); return new ResponseEntity<>(loginUserDto,headers, HttpStatus.OK); }
@RequestMapping(value="/login",method=RequestMethod.POST) public ModelAndView login(User user, String captcha, HttpSession session,HttpServletRequest request) throws Exception{ ModelAndView mv = new ModelAndView(); String kaptchaExpected = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); System.out.println(kaptchaExpected); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); try{ subject.login(token); mv.setViewName("redirect:/index.jsp"); } catch (AuthenticationException e){ mv.addObject("message", "login errors"); mv.setViewName("redirect:/backend/login"); } return mv; }
@RequestMapping(value ="/hello") @ResponseBody public String hello(){ Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhansan", "123456"); //--4. 登录,即身份验证 try { subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); } //System.out.println(subject.isAuthenticated()); //System.out.println(subject.getPrincipal()); //-- 6. 退出 System.out.println(subject.isAuthenticated()); subject.logout(); return "hello"; }
/** * 登录 * @param user * @param session * @param request * @return * @throws Exception */ @SystemControllerLog(description="登录系统") @RequestMapping(value="/login",method=RequestMethod.POST) public ModelAndView login(User user, HttpSession session,HttpServletRequest request) throws Exception{ ModelAndView mv = new ModelAndView(); Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(),user.getUserPass()); try{ currentUser.login(token); mv.setViewName("redirect:/index.jsp"); } catch (AuthenticationException e){ mv.addObject("message", "login errors"); mv.setViewName("redirect:/backend/login"); } return mv; }
/** * 先执行登录验证 * @param token * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //获取用户名密码 String username = token.getPrincipal().toString(); TbUser tbUser = userService.getUserByUsername(username); if (tbUser != null){ //得到用户账号和密码存放到authenticationInfo中用于Controller层的权限判断 第三个参数随意不能为null AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(tbUser.getUsername(),tbUser.getPassword(), tbUser.getUsername()) ; return authenticationInfo ; }else{ return null ; } }
@PostMapping("/login") public String login(HttpServletRequest request, User user, Model model){ if (StringUtils.isEmpty(user.getLoginId()) || StringUtils.isEmpty(user.getPassword())) { request.setAttribute("msg", "用户名或密码不能为空!"); return "login"; } Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(user.getLoginId(),user.getPassword()); try { subject.login(token); return "manage"; }catch (LockedAccountException lae) { token.clear(); request.setAttribute("msg", "用户已经被锁定不能登录,请与管理员联系!"); return "login"; } catch (AuthenticationException e) { token.clear(); request.setAttribute("msg", "用户或密码不正确!"); return "login"; } }
/** * testIniRealm * @Description: iniRealm的测试 * @return: void * @Author: BeautifulSoup * @Date: 2017年12月16日 上午11:41:43 */ @Test @Ignore public void testIniRealm(){ Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:inirealm-shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken("james_shu", "1997admin"); try{ subject.login(token); }catch(AuthenticationException e){ e.printStackTrace(); } System.out.println("用户认证状态:"+subject.isAuthenticated()); subject.logout(); System.out.println("用户当前认证状态:"+subject.isAuthenticated()); }
/** * testCustomRealm * @Description: CustomRealm的测试 * @return: void * @Author: BeautifulSoup * @Date: 2017年12月16日 上午11:41:53 */ @Test public void testCustomRealm(){ Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:customrealm-shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken("BeautifulSoup", "1997admin"); try{ subject.login(token); }catch(AuthenticationException e){ e.printStackTrace(); } System.out.println("用户认证状态:"+subject.isAuthenticated()); subject.logout(); System.out.println("用户当前认证状态:"+subject.isAuthenticated()); }
/** * testIniAuthorization * @Description: 使用inirealm完成授权 * @return: void * @Author: BeautifulSoup * @Date: 2017年12月16日 下午3:05:34 */ @Test @Ignore public void testIniAuthorization(){ Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:permission-shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); //首先认证,认证通过之后才能授权 UsernamePasswordToken token=new UsernamePasswordToken("beautifulsoup", "password"); try{ subject.login(token); }catch(AuthenticationException e){ e.printStackTrace(); } System.out.println("用户的认证状态:"+subject.isAuthenticated()); boolean isPermitted=subject.isPermittedAll("user:create:01","user:query"); subject.checkPermissions("user:create:01","user:query"); System.out.println(isPermitted); }
/** * testCustomRealmAuthorization * @Description: 使用自定义realm完成授权 * @return: void * @Author: BeautifulSoup * @Date: 2017年12月16日 下午3:05:46 */ @Test public void testCustomRealmAuthorization(){ Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:customrealm-shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); //首先认证,认证通过之后才能授权 UsernamePasswordToken token=new UsernamePasswordToken("BeautifulSoup", "1997admin"); try{ subject.login(token); }catch(AuthenticationException e){ e.printStackTrace(); } System.out.println("用户的认证状态:"+subject.isAuthenticated()); boolean isPermitted=subject.isPermittedAll("item:query"); System.out.println(isPermitted); }
/** * 登录失败调用事件 */ @Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { String className = e.getClass().getName(), message = ""; if (IncorrectCredentialsException.class.getName().equals(className) || UnknownAccountException.class.getName().equals(className)){ message = "用户或密码错误, 请重试."; } else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){ message = StringUtils.replace(e.getMessage(), "msg:", ""); } else{ message = "系统出现点问题,请稍后再试!"; e.printStackTrace(); // 输出到控制台 } request.setAttribute(getFailureKeyAttribute(), className); request.setAttribute(getMessageParam(), message); return true; }
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; Map<String, Object> params = new HashMap<String, Object>(); params.put("enable", 1); params.put("account", token.getUsername()); Parameter parameter = new Parameter("sysUserService", "queryList").setMap(params); logger.info("{} execute sysUserService.queryList start...", parameter.getNo()); List<?> list = provider.execute(parameter).getList(); logger.info("{} execute sysUserService.queryList end.", parameter.getNo()); if (list.size() == 1) { SysUser user = (SysUser) list.get(0); StringBuilder sb = new StringBuilder(100); for (int i = 0; i < token.getPassword().length; i++) { sb.append(token.getPassword()[i]); } if (user.getPassword().equals(sb.toString())) { WebUtil.saveCurrentUser(user.getId()); saveSession(user.getAccount(), token.getHost()); AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getAccount(), user.getPassword(), user.getUserName()); return authcInfo; } logger.warn("USER [{}] PASSWORD IS WRONG: {}", token.getUsername(), sb.toString()); return null; } else { logger.warn("No user: {}", token.getUsername()); return null; } }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // token是用户输入的用户名和密码 // 第一步从token中取出用户名 String userCode = (String) token.getPrincipal(); // 如果查询不到返回null //数据库中用户账号是zhangsansan // if(!userCode.equals("zhangsansan")){// // return null; // } // 模拟从数据库查询到密码 String password = "111111"; //将activeUser设置simpleAuthenticationInfo SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( userCode, password, this.getName()); return simpleAuthenticationInfo; }
@Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setContentType("application/json;charset=utf-8"); try { //处理登录失败的异常 Throwable throwable = e.getCause() == null ? e : e.getCause(); Result result = Result.error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage()); String json = new Gson().toJson(result); httpResponse.getWriter().print(json); } catch (IOException e1) { e1.printStackTrace(); } return false; }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal();// 根据刚刚传过来的token获取用户名 Blogger blogger = bloggerService.findByUsername(username);// 只是根据用户名查询出,不涉及密码 if (blogger != null) { System.out.println("验证信息:" + blogger); // 把获取到的用户存到session中 SecurityUtils.getSubject().getSession().setAttribute("blogger", blogger); // 把从数据库中查询出来的博主信息放到AuthenticationInfo中,即把正确的用户名,密码,交给shiro,再和前台输入的校验。 AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(blogger.getUsername(), blogger.getPassword(), "MyRealm"); return authenticationInfo; } else { return null; } }
/** * 认证回调函数,登录时调用. */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; // User user = accountManager.findUserByLoginName(token.getUsername()); //根据loginToken 看能不查到当前token token有效期就1分钟 String tokenPassword=new String(token.getPassword()); User user = accountManager.findUserByLoginNameOrEmail(token.getUsername()); //user.getStandardLock()==1 if (user != null && user.getStatus().intValue()!=0 && !user.getLoginName().endsWith("@chacuo.net")) { return new SimpleAuthenticationInfo(user.getLoginName(), user.getShaPassword() , getName()); } else { return null; } }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { BearerToken token = (BearerToken)arg0; // assert the bearerToken, and if valid, look up the account data and return //an AuthenticationInfo instance representing that account. String email = (String)token.getPrincipal(); String credentials = (String)token.getCredentials(); Preconditions.checkNotNull(email, "Email can't be null"); Preconditions.checkNotNull(token, "Token can't be null"); DBAuthenticationToken dbToken = tokenRepository.getAuthenticationToken(credentials) ; if (tokenIsInvalid(token, dbToken)) { LOGGER.info("Rejecting token " + credentials + " for user " + email); return null; } return new BearerAuthenticationInfo(this, dbToken); }
@RequestMapping(value="/login",method=RequestMethod.POST) public ModelAndView login(User user, String captcha, HttpSession session,HttpServletRequest request) throws Exception{ ModelAndView mv = new ModelAndView(); String kaptchaExpected = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); //--System.out.println(kaptchaExpected); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); try{ subject.login(token); System.out.println(subject.getSession().getId()); System.out.println(session.getId()); mv.setViewName("redirect:/hello"); } catch (AuthenticationException e){ mv.addObject("message", "login errors"); mv.setViewName("redirect:/backend/login"); } return mv; }
/** * 登录认证,在权限认证前执行 * * @param token * @return AuthenticationInfo * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = token.getPrincipal().toString(); UUser user = userMService.findUserByUserName(username); if (null == user) { return null; } else { /** * info中principal选择方案:1.username, 2.User, 3.UserWithRoleAndPermission * 各有优劣,这里选择使用username * * EAO isssue: 新建对象WholeUser,有属性roles,permissions,登录时产生此对象作为principals,则authorization时无需再和sql交互 * 1.优势: 减少sql交互, * 2.劣势:缓存大,对变更的用户信息反馈不及时 * 适用: 变化不大信息量少,但权限校验频繁的用户类型. * * SimpleAuthorizationInfo: param: principal检查源码最后被强转为Collection不知何意?? */ SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), "UserRealm"); return info; } }
/** * 登录认证,在权限认证前执行 * * @param token * @return AuthenticationInfo * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String userName = token.getPrincipal().toString(); UUser user = userFService.findUserByUsername(userName); if (null == user) { return null; } else { /** * info中principal选择方案:1.username, 2.User, 3.UserWithRoleAndPermission * 各有优劣,这里选择使用username * * EAO isssue: 新建对象WholeUser,有属性roles,permissions,登录时产生此对象作为principals,则authorization时无需再和sql交互 * 1.优势: 减少sql交互, * 2.劣势:缓存大,对变更的用户信息反馈不及时 * 适用: 变化不大信息量少,但权限校验频繁的用户类型. * * SimpleAuthorizationInfo: param: principal检查源码最后被强转为Collection不知何意?? */ SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), "UserRealm"); return info; } }
@Test public void testLoginFailure401() { subject.login(isA(AuthenticationToken.class)); expectLastCall().andThrow(new AuthenticationException()); replayAndStart(); ClientResponse clientResponse = getRequestBuilder(PATH) .header(HttpHeaders.AUTHORIZATION, ShiroKerberosAuthenticationFilter.NEGOTIATE + " asdf") .get(ClientResponse.class); assertEquals(HttpServletResponse.SC_UNAUTHORIZED, clientResponse.getStatus()); assertEquals( ShiroKerberosAuthenticationFilter.NEGOTIATE, clientResponse.getHeaders().getFirst(HttpHeaders.WWW_AUTHENTICATE)); }
/** * 在每个Realm之后调用 */ @Override public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException { AuthenticationInfo authenticationInfo = null; if(singleRealmInfo == null){//当前没有通过验证 authenticationInfo = aggregateInfo;//保存之前所合并的 }else{//通过验证 if(aggregateInfo== null){//之前没有合并过 authenticationInfo = singleRealmInfo;//初始化 }else{ authenticationInfo = merge(singleRealmInfo, aggregateInfo);//合并 if(authenticationInfo.getPrincipals().getRealmNames().size() > 1){ System.out.println(authenticationInfo.getPrincipals().getRealmNames()); throw new AuthenticationException("[" + token.getClass() + "] " + "这个认证令牌无法通过realm的验证,请确认您提供的令牌只允许通过1个realm验证"); } } } return authenticationInfo; }
/** * 登录失败调用事件 */ @Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { String className = e.getClass().getName(), message = ""; if (IncorrectCredentialsException.class.getName().equals(className) || UnknownAccountException.class.getName().equals(className)) { message = "用户或密码错误, 请重试."; } else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")) { message = StringUtils.replace(e.getMessage(), "msg:", ""); } else { message = "系统出现点问题,请稍后再试!"; e.printStackTrace(); // 输出到控制台 } request.setAttribute(getFailureKeyAttribute(), className); request.setAttribute(getMessageParam(), message); return true; }
/** * 执行登录请求 * * @param username * @param request * @return */ private String login(String username, String accessToken, HttpServletRequest request) { String ret = getView(Views.LOGIN); if (StringUtils.isNotBlank(username)) { AuthenticationToken token = createToken(username, accessToken); try { SecurityUtils.getSubject().login(token); ret = Views.REDIRECT_HOME; } catch (AuthenticationException e) { logger.error(e); if (e instanceof UnknownAccountException) { throw new MtonsException("用户不存在"); } else if (e instanceof LockedAccountException) { throw new MtonsException("用户被禁用"); } else { throw new MtonsException("用户认证失败"); } } return ret; } throw new MtonsException("登录失败!"); }
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; /* if (Strings.isBlank(upToken.getCaptcha())) throw new AuthenticationException("验证码不能为空"); String _captcha = Strings.sBlank(SecurityUtils.getSubject().getSession(true).getAttribute(Toolkit.captcha_attr)); if (!upToken.getCaptcha().equalsIgnoreCase(_captcha)) throw new AuthenticationException("验证码错误");*/ User user = dao().fetch(User.class, Cnd.where("name", "=", upToken.getUsername())); if (user == null) return null; if (user.isLocked()) throw new LockedAccountException("Account [" + upToken.getUsername() + "] is locked."); ByteSource salt = ByteSource.Util.bytes(user.getSalt()); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), getName()); info.setCredentialsSalt(salt); return info; }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String phoneNumber = (String)token.getPrincipal(); if(StringUtils.trimToNull(phoneNumber) == null){ throw new IncorrectCredentialsException();//账号或密码错误 } CdMember query = new CdMember(); query.setPhoneNumber(phoneNumber); CdMember member = memberService.findMember(query); if(member == null) { throw new UnknownAccountException();//没找到帐号 } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( phoneNumber, //用户名 member.getPassword(), //密码 ByteSource.Util.bytes(AppConstants.PC_PASSWORD_SALT),//salt=phoneNumber getName() //realm name ); return authenticationInfo; }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String)token.getPrincipal(); SysUsers user = userService.findByUsername(username); if(user == null) { throw new UnknownAccountException();//没找到帐号 } if(Boolean.TRUE.equals(user.getLocked())) { throw new LockedAccountException(); //帐号锁定 } //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( username, //用户名 user.getPassword(), //密码 ByteSource.Util.bytes(user.getSalt()),//salt=salt getName() //realm name ); return authenticationInfo; }
@Override protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException { assertRealmsConfigured(); //根据不同类型的token找对应的的Realm String realmKey = ""; if(authenticationToken instanceof MemberUserToken) { realmKey = ((MemberUserToken)authenticationToken).getRealmKey(); } else if(authenticationToken instanceof SysUserToken) { realmKey = ((SysUserToken)authenticationToken).getRealmKey(); } if(StringUtils.isEmpty(realmKey)) { // 抛异常还是支持multiple Realms // return doMultiRealmAuthentication(realms, authenticationToken); throw new AuthenticationException("不支持token:" + authenticationToken.getClass().getName()); } else { Realm realm = lookupRealm(realmKey); return doSingleRealmAuthentication(realm, authenticationToken); } }
@Test public void testFullStack() { Realm mockRealm = mockRealm(); BQRuntime runtime = testFactory.app() .module(b -> ShiroModule.extend(b).addRealm(mockRealm)) .autoLoadModules() .createRuntime(); Subject subject = new Subject.Builder(runtime.getInstance(SecurityManager.class)).buildSubject(); assertFalse(subject.isAuthenticated()); // try bad login try { subject.login(new UsernamePasswordToken("uname", "badpassword")); Assert.fail("Should have thrown on bad auth"); } catch (AuthenticationException authEx) { assertFalse(subject.isAuthenticated()); } // try good login subject.login(new UsernamePasswordToken("uname", "password")); assertTrue(subject.isAuthenticated()); }