Spring Security OAuth2.0 自定义token生成方式

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

系统集成了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

Spring Security OAuth2.0 自定义token生成方式_第1张图片

这个版本的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

Service:

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返回的程序。这里只是演示流程。

 

转载于:https://my.oschina.net/taoyuanping/blog/809157

你可能感兴趣的:(Spring Security OAuth2.0 自定义token生成方式)