[SPRING] spring-oauth2 로그인 성공 처리기
SPRINGspring-oauth2 로그인 성공 처리기
spring-oauth2를 사용하여 로그인 성공 처리기를 추가하는 방법이 있습니까?
기본 인증 필터를 사용하여 시도했지만 사용자 자격 증명이 아닌 클라이언트 자격 증명 만 필터링합니다.
또는 사용자 정의 사용자 인증 관리자를 만들어야합니까?
티아
해결법
-
==============================
1.이 솔루션은 암호 흐름 및 다른 사람들을 위해 잘 모르겠습니다. oauth-server config에있는 http 태그의 "before = BASIC_AUTH_FILTER"위치에 사용자 정의 필터를 추가 할 수 있습니다. "oauth / token"응답을 구문 분석하여 달성 할 수 있으므로 응답을 얻으려면 ByteArrayResponseWrapper를 작성하고, 여기서는 "org.apache.commons commons-io"의 TeeOutputStream 클래스를 사용하고 있습니다.
이 솔루션은 암호 흐름 및 다른 사람들을 위해 잘 모르겠습니다. oauth-server config에있는 http 태그의 "before = BASIC_AUTH_FILTER"위치에 사용자 정의 필터를 추가 할 수 있습니다. "oauth / token"응답을 구문 분석하여 달성 할 수 있으므로 응답을 얻으려면 ByteArrayResponseWrapper를 작성하고, 여기서는 "org.apache.commons commons-io"의 TeeOutputStream 클래스를 사용하고 있습니다.
private class ByteArrayResponseWrapper extends HttpServletResponseWrapper { public ByteArrayResponseWrapper(ServletResponse response) { super((HttpServletResponse) response); } private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); @Override public ServletOutputStream getOutputStream() throws IOException { return new DelegatingServletOutputStream(new TeeOutputStream( super.getOutputStream(), byteArrayOutputStream)); } public byte[] getByteArray() { return this.byteArrayOutputStream.toByteArray(); } }
나는 토큰 추출기를 생성하여 access_token을 추출하는 코드를 분리했다.
public class OAuth2AccessTokenExtractor implements OAuth2AccessTokenExtractor { private ObjectMapper mapper = new ObjectMapper(); public String getAccessTokenValue(byte[] response) { try { return mapper.readValue(response, OAuth2AccessToken.class) .getValue(); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } }
필터를 만든 후 doFilter를 다음과 같이 재정의하십시오.
private DefaultTokenServices tokenServices; private OAuth2AccessTokenExtractor tokenExtractor; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // create wrapper to read response body ByteArrayResponseWrapper responseWraper = new ByteArrayResponseWrapper( response); // led them go chain.doFilter(request, responseWraper); // get ClientAuthentication Authentication clientAuthentication = SecurityContextHolder .getContext().getAuthentication(); // is authenticated or not to proceed if (clientAuthentication != null && clientAuthentication.isAuthenticated()) { // callBack client authenticated successfully onSuccessfulClientAuthentication(request, response, clientAuthentication); // check response status is success of failure if (responseWraper.getStatus() == 200) { // extract accessToken from response String token = tokenExtractor .getAccessTokenValue(responseWraper.getByteArray()); if (token != null && !token.isEmpty()) { // load authentication from token OAuth2Authentication oAuth2Authentication = this.tokenServices .loadAuthentication(token); OAuth2AccessToken actualAccessToken = this.tokenServices .getAccessToken(oAuth2Authentication); // callBack user authenticated successfully onSuccessfulUserAuthentication(request, response, clientAuthentication, oAuth2Authentication, actualAccessToken); } else { log.error("access token is empty from extractor"); } } else { // callBack user authenticated failure onFailureUserAuthentication(request, response, clientAuthentication, request.getParameter("username")); } } else { // callBack client authenticated failure onFailClientAuthentication(request, response, request.getParameter(OAuth2Utils.CLIENT_ID)); } } protected void onSuccessfulClientAuthentication(ServletRequest request, ServletResponse response, Authentication authentication) { } protected void onFailClientAuthentication(ServletRequest request, ServletResponse response, String clientId) { } protected void onSuccessfulUserAuthentication(ServletRequest request, ServletResponse response, Authentication clientAuthentication, OAuth2Authentication userOAuth2Authentication, OAuth2AccessToken token) { } protected void onFailureUserAuthentication(ServletRequest request, ServletResponse response, Authentication clientAuthentication, String username) { }
필터 인스턴스 인젝션 tokenServices를 생성합니다. OnSuccessfulClientAuthentication, onFailClientAuthentication, onSuccessfulUserAuthentication 및 onFailureUserAuthentication이 인증에 따라 호출됩니다.
더 많은 정보는 github에서이 코드를 참조하십시오.
편집 됨 :
위의 스 니펫은 기본 토큰 응답이 있고 ServletResponseWrapper를 사용하고 추출 할 때 잘 작동합니다. 하지만 여전히 취약한 것처럼 보이므로 org.springframework.security.oauth2.provider.token.TokenEnhancer 클래스를 통해 사용자 인증 성공을 알 수 있습니다.
자세한 내용은이 답변을 따르십시오.
-
==============================
2.이 작업을 수행하기 위해 OAuth2AuthenticationProcessingFilter에 연결 한 사용자 정의 인증 관리자를 구축했습니다. 관리자의 authenticate 메소드는 인증 주체에서 OAuth2Authentication 및 OAuth2AuthenticationDetails의 압축을 풀 수 있습니다.
이 작업을 수행하기 위해 OAuth2AuthenticationProcessingFilter에 연결 한 사용자 정의 인증 관리자를 구축했습니다. 관리자의 authenticate 메소드는 인증 주체에서 OAuth2Authentication 및 OAuth2AuthenticationDetails의 압축을 풀 수 있습니다.
<bean id="oAuth2AuthenticationManager" class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager"> <property name="resourceId" value="XXX-api"/> <property name="tokenServices" ref="tokenServices"/> </bean> <bean id="resourceServerFilter" class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter"> <property name="authenticationManager" ref="oAuth2AuthenticationManager"/> <property name="tokenExtractor"> <bean class="com.xxx.oauth.BearerTokenExtractor"/> </property> </bean>
from https://stackoverflow.com/questions/29339027/spring-oauth2-login-success-handler by cc-by-sa and MIT license