Skip to content

Commit

Permalink
6-4
Browse files Browse the repository at this point in the history
  • Loading branch information
jojozhai committed Sep 10, 2017
1 parent 5cab9b6 commit 82b5f06
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,76 @@
*/
package com.imooc.security.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.social.security.SpringSocialConfigurer;

import com.imooc.security.core.authentication.mobile.SmsCodeAuthenticationSecurityConfig;
import com.imooc.security.core.properties.SecurityConstants;
import com.imooc.security.core.properties.SecurityProperties;
import com.imooc.security.core.validate.code.ValidateCodeSecurityConfig;

/**
* @author zhailiang
*
*/
@Configuration
@EnableResourceServer
public class ImoocResourceServerConfig {
public class ImoocResourceServerConfig extends ResourceServerConfigurerAdapter {

@Autowired
protected AuthenticationSuccessHandler imoocAuthenticationSuccessHandler;

@Autowired
protected AuthenticationFailureHandler imoocAuthenticationFailureHandler;

@Autowired
private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;

@Autowired
private ValidateCodeSecurityConfig validateCodeSecurityConfig;

@Autowired
private SpringSocialConfigurer imoocSocialSecurityConfig;

@Autowired
private SecurityProperties securityProperties;

@Override
public void configure(HttpSecurity http) throws Exception {

http.formLogin()
.loginPage(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL)
.loginProcessingUrl(SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_FORM)
.successHandler(imoocAuthenticationSuccessHandler)
.failureHandler(imoocAuthenticationFailureHandler);

http//.apply(validateCodeSecurityConfig)
// .and()
.apply(smsCodeAuthenticationSecurityConfig)
.and()
.apply(imoocSocialSecurityConfig)
.and()
.authorizeRequests()
.antMatchers(
SecurityConstants.DEFAULT_UNAUTHENTICATION_URL,
SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE,
securityProperties.getBrowser().getLoginPage(),
SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX+"/*",
securityProperties.getBrowser().getSignUpUrl(),
securityProperties.getBrowser().getSession().getSessionInvalidUrl(),
securityProperties.getBrowser().getSignOutUrl(),
"/user/regist")
.permitAll()
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,26 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.security.core.properties.LoginResponseType;
import com.imooc.security.core.properties.SecurityProperties;

/**
Expand All @@ -35,6 +46,12 @@ public class ImoocAuthenticationSuccessHandler extends SavedRequestAwareAuthenti
@Autowired
private SecurityProperties securityProperties;

@Autowired
private ClientDetailsService clientDetailsService;

@Autowired
private AuthorizationServerTokenServices authorizationServerTokenServices;

/*
* (non-Javadoc)
*
Expand All @@ -43,19 +60,64 @@ public class ImoocAuthenticationSuccessHandler extends SavedRequestAwareAuthenti
* HttpServletRequest, javax.servlet.http.HttpServletResponse,
* org.springframework.security.core.Authentication)
*/
@SuppressWarnings("unchecked")
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {

logger.info("登录成功");

if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(authentication));
} else {
super.onAuthenticationSuccess(request, response, authentication);
String header = request.getHeader("Authorization");

if (header == null || !header.startsWith("Basic ")) {
throw new UnapprovedClientAuthenticationException("请求头中无client信息");
}

String[] tokens = extractAndDecodeHeader(header, request);
assert tokens.length == 2;

String clientId = tokens[0];
String clientSecret = tokens[1];

ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

if (clientDetails == null) {
throw new UnapprovedClientAuthenticationException("clientId对应的配置信息不存在:" + clientId);
} else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {
throw new UnapprovedClientAuthenticationException("clientSecret不匹配:" + clientId);
}

TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom");

OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);

OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);

OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(token));

}

private String[] extractAndDecodeHeader(String header, HttpServletRequest request) throws IOException {

byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new BadCredentialsException("Failed to decode basic authentication token");
}

String token = new String(decoded, "UTF-8");

int delim = token.indexOf(":");

if (delim == -1) {
throw new BadCredentialsException("Invalid basic authentication token");
}
return new String[] { token.substring(0, delim), token.substring(delim + 1) };
}

}

0 comments on commit 82b5f06

Please sign in to comment.