CAS单点登录-自定义认证之Shiro、Rest(六)

客户端校验Demo


SysUser.java

/*

  • 版权所有.©2008-2017. 卡尔科技工作室

*/

package com.carl.auth.sso.rest.client.bean;

import com.fasterxml.jackson.annotation.JsonIgnore;

import com.fasterxml.jackson.annotation.JsonProperty;

import javax.validation.constraints.NotNull;

import java.util.HashMap;

import java.util.Map;

/**

  • @author Carl

  • @date 2017/9/14

  • @since JDK1.7

*/

public class SysUser {

@JsonProperty(“id”)

@NotNull

private String username;

@JsonProperty(“@class”)

//需要返回实现org.apereo.cas.authentication.principal.Principal的类名接口

private String clazz = “org.apereo.cas.authentication.principal.SimplePrincipal”;

@JsonProperty(“attributes”)

private Map<String, Object> attributes = new HashMap<>();

@JsonIgnore

@NotNull

private String password;

@JsonIgnore

//用户是否不可用

private boolean disable = false;

@JsonIgnore

//用户是否过期

private boolean expired = false;

@JsonIgnore

//是否锁定

private boolean locked = false;

public boolean isLocked() {

return locked;

}

public SysUser setLocked(boolean locked) {

this.locked = locked;

return this;

}

public boolean isDisable() {

return disable;

}

public SysUser setDisable(boolean disable) {

this.disable = disable;

return this;

}

public boolean isExpired() {

return expired;

}

public SysUser setExpired(boolean expired) {

this.expired = expired;

return this;

}

public String getPassword() {

return password;

}

public SysUser setPassword(String password) {

this.password = password;

return this;

}

public String getUsername() {

return username;

}

public SysUser setUsername(String username) {

this.username = username;

return this;

}

public String getClazz() {

return clazz;

}

public Map<String, Object> getAttributes() {

return attributes;

}

public SysUser setAttributes(Map<String, Object> attributes) {

this.attributes = attributes;

return this;

}

@JsonIgnore

public SysUser addAttribute(String key, Object val) {

getAttributes().put(key, val);

return this;

}

}

而上面的属性,必须跟@class的实现一一对应,如attributes 就是返回属性给对接的客户端,有必要的信息必须返回给cas,cas会进行二次过滤,而二次过滤是属于多属性返回的内容,后面的章节会说明白哦


AuthUserController.java

/*

  • 版权所有.©2008-2017. 卡尔科技工作室

*/

package com.carl.auth.sso.rest.client.controller;

import com.carl.auth.sso.rest.client.bean.SysUser;

import com.carl.auth.sso.rest.client.service.UserRepertory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.util.Base64Utils;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestHeader;

import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;

/**

  • @author Carl

  • @date 2017/9/14

  • @since JDK1.7

*/

@RestController

public class AuthUserController {

private static final Logger LOGGER = LoggerFactory.getLogger(AuthUserController.class);

@Autowired

private UserRepertory userRepertory;

/**

    1. cas 服务端会通过post请求,并且把用户信息以"用户名:密码"进行Base64编码放在authorization请求头中
    1. 返回200状态码并且格式为{“@class”:“org.apereo.cas.authentication.principal.SimplePrincipal”,“id”:“casuser”,“attributes”:{}} 是成功的
    1. 返回状态码403用户不可用;404账号不存在;423账户被锁定;428过期;其他登录失败
  • @param httpHeaders

  • @return

*/

@PostMapping(“/login”)

public Object login(@RequestHeader HttpHeaders httpHeaders) {

LOGGER.info(“Rest api login.”);

LOGGER.debug(“request headers: {}”, httpHeaders);

SysUser user = null;

try {

UserTemp userTemp = obtainUserFormHeader(httpHeaders);

//尝试查找用户库是否存在

user = userRepertory.getUser(userTemp.username);

if (user != null) {

if (!user.getPassword().equals(userTemp.password)) {

//密码不匹配

return new ResponseEntity(HttpStatus.BAD_REQUEST);

}

if (user.isDisable()) {

//禁用 403

return new ResponseEntity(HttpStatus.FORBIDDEN);

}

if (user.isLocked()) {

//锁定 423

return new ResponseEntity(HttpStatus.LOCKED);

}

if (user.isExpired()) {

//过期 428

return new ResponseEntity(HttpStatus.PRECONDITION_REQUIRED);

}

} else {

//不存在 404

return new ResponseEntity(HttpStatus.NOT_FOUND);

}

} catch (UnsupportedEncodingException e) {

LOGGER.error(“”, e);

new ResponseEntity(HttpStatus.BAD_REQUEST);

}

LOGGER.info(“[{}] login is ok”, user.getUsername());

//成功返回json

return user;

}

/**

  • 根据请求头获取用户名及密码

  • @param httpHeaders

  • @return

  • @throws UnsupportedEncodingException

*/

private UserTemp obtainUserFormHeader(HttpHeaders httpHeaders) throws UnsupportedEncodingException {

/**

  • This allows the CAS server to reach to a remote REST endpoint via a POST for verification of credentials.

  • Credentials are passed via an Authorization header whose value is Basic XYZ where XYZ is a Base64 encoded version of the credentials.

*/

//根据官方文档,当请求过来时,会通过把用户信息放在请求头authorization中,并且通过Basic认证方式加密

String authorization = httpHeaders.getFirst(“authorization”);//将得到 Basic Base64(用户名:密码)

String baseCredentials = authorization.split(" ")[1];

String usernamePassword = new String(Base64Utils.decodeFromString(baseCredentials), “UTF-8”);//用户名:密码

LOGGER.debug(“login user: {}”, usernamePassword);

String credentials[] = usernamePassword.split(“:”);

return new UserTemp(credentials[0], credentials[1]);

}

/**

  • 解析请求过来的用户

*/

private class UserTemp {

private String username;

private String password;

public UserTemp(String username, String password) {

this.username = username;

this.password = password;

}

}

}

这段代码核心是实现cas明确要求的返回值,如果敢兴趣,请仔细看注解

若尝试用户rest-locked/admin结果如下

这里写图片描述

总结

==

  1. shiro的使用率及集成

  2. rest的应用场景及集成

cas的认证方式中,最常见三种校验方式:

  • 数据库查询(上一章)

  • shiro集成验证(本章)

  • 远程rest认证(本章)

相信很多人对自定义校验器非常感兴趣,例如验证码登录、扫码登录等等,那么这些再后面再继续说

因为验证码登录必须先把界面调整,这是主题的范畴,回过头再讲自定义。

最后

看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。

开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题

注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友

最新“美团+字节+腾讯”一二三面问题,挑战一下你能走到哪一面?

互联网工程师必备的面试1000题

而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题

最新“美团+字节+腾讯”一二三面问题,挑战一下你能走到哪一面?

验器`非常感兴趣,例如验证码登录、扫码登录等等,那么这些再后面再继续说

因为验证码登录必须先把界面调整,这是主题的范畴,回过头再讲自定义。

最后

看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。

开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题

注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友

[外链图片转存中…(img-dko8pirU-1721832808617)]

互联网工程师必备的面试1000题

而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题

[外链图片转存中…(img-tKey0G1X-1721832808618)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值