2019独角兽企业重金招聘Python工程师标准>>>
系统集成了CAS,所以使用Spring Security OAuth2.0时是不能使用password这种方式的,但是可以自定义一种token的生成方式,使用cas_ticket代替password授权方式。
开始之前还请移步 参考我的另一篇博客 https://my.oschina.net/taoyuanping/blog/806601
1、配置xml
1.1 新增授权方式
新增
1.2 配置cas_ticket授权方式
1.3 配置允许客户端使用cas_ticket方式
2、创建CasTicketTokenGranter类
public class CasTicketTokenGranter extends AbstractTokenGranter {
private static final String GRANT_TYPE = "cas_ticket";
private final AuthenticationManager authenticationManager;
public CasTicketTokenGranter(AuthenticationManager authenticationManager,
AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
}
protected CasTicketTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices,
ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
super(tokenServices, clientDetailsService, requestFactory, grantType);
this.authenticationManager = authenticationManager;
}
@Override
public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
OAuth2AccessToken token = super.grant(grantType, tokenRequest);
if (token != null) {
DefaultOAuth2AccessToken norefresh = new DefaultOAuth2AccessToken(token);
// The spec says that cas ticket should not be allowed to get a refresh token
norefresh.setRefreshToken(null);
token = norefresh;
}
return token;
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map parameters = new LinkedHashMap(tokenRequest.getRequestParameters());
String username = CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER;
String password = parameters.get(ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER);
if (password == null) {
throw new InvalidRequestException("A cas ticket must be supplied.");
}
Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password);
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
try {
userAuth = authenticationManager.authenticate(userAuth);
}
catch (AccountStatusException ase) {
//covers expired, locked, disabled cases (mentioned in section 5.2, draft 31)
throw new InvalidGrantException(ase.getMessage());
}
catch (BadCredentialsException e) {
// If the ticket is wrong the spec says we should send 400/invalid grant
throw new InvalidGrantException(e.getMessage());
}
if (userAuth == null || !userAuth.isAuthenticated()) {
throw new InvalidGrantException("Could not authenticate ticket: " + password);
}
OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
return new OAuth2Authentication(storedOAuth2Request, userAuth);
}
}
3、配置cas服务器开启REST
3.1 添加依赖
org.jasig.cas
cas-server-support-rest
${cas.version}
使用的是4.2.7版本
3.2 配置web.xml
这个版本的cas webapp 里的 web.xml 已经有rest的配置了
4、测试
4.1 客户端使用用户名密码获取TGT
@Test
public void getCasTgt() {
Map params = new HashMap();
params.put("username", "admin");
params.put("password", "123456");
String rsp = null;
try {
rsp = WebUtils.doPost("https://cas.yakee.net:8443/cas/v1/tickets", params, 3000, 15000);
System.out.println(rsp);
} catch (Exception e) {
e.printStackTrace();
}
}
返回
201 Created
TGT Created
4.2 使用TGT获取ticket
@Test
public void getCasTicketByTgt() {
Map params = new HashMap();
params.put("service", "http://www.yakee.net:8080/framework/login/cas");
String rsp = null;
try {
rsp = WebUtils.doPost("https://cas.yakee.net:8443/cas/v1/tickets/"
+ "TGT-13-7h2UIaWBwqm9y6OlRC9eCi1xQSmzQMLDQuenopDeXbKFxQnzpt-cas.yakee.net", params, 3000, 15000);
System.out.println(rsp);
} catch (Exception e) {
e.printStackTrace();
}
}
返回
ST-34-VUsTHVGKo1ty7hvH3WG0-cas.yakee.net
4.2 使用ticket获取access_token
@Test
public void getTokenByCasTicket() {
Map params = new HashMap();
params.put("grant_type", "cas_ticket");
params.put("client_secret", "456");
params.put("client_id", "123");
params.put("ticket", "ST-34-VUsTHVGKo1ty7hvH3WG0-cas.yakee.net");
String rsp = null;
try {
rsp = WebUtils.doPost("http://www.yakee.net:8080/framework/oauth/token", params, 3000, 15000);
System.out.println(rsp);
} catch (Exception e) {
e.printStackTrace();
}
}
这里肯定会失败,因为ticket的过期时间只有10s,所以正式环境需要一个解析cas返回的程序。这里只是演示流程。