2017-10-05 8 views
0

마이크로 서비스를 보호하기 위해 스프링 클라우드 보안 및 Oauth2를 사용하고 있습니다. 이제 폼은은 다음과 같다 :마이크로 서비스 스프링 클라우드 보안 보안 Oauth2

http://maven.apache.org/xsd/maven-4.0.0.xsd "> 4.0.0

<groupId>com.oreilly.cloud</groupId> 
<artifactId>spring-microservices-oauth-server</artifactId> 
<version>0.0.1-SNAPSHOT</version> 
<packaging>jar</packaging> 

<name>spring-microservices-oauth-server</name> 
<description>Demo project for Spring Boot</description> 

<parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.5.7.RELEASE</version> 
    <relativePath/> <!-- lookup parent from repository --> 
</parent> 

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
    <java.version>1.8</java.version> 
    <spring-cloud.version>Dalston.SR3</spring-cloud.version> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>org.springframework.cloud</groupId> 
     <artifactId>spring-cloud-starter-oauth2</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-jdbc</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-security</artifactId> 
    </dependency> 

    <dependency> 
     <groupId>org.hsqldb</groupId> 
     <artifactId>hsqldb</artifactId> 
     <scope>runtime</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-test</artifactId> 
     <scope>test</scope> 
    </dependency> 
</dependencies> 

<dependencyManagement> 
    <dependencies> 
     <dependency> 
      <groupId>org.springframework.cloud</groupId> 
      <artifactId>spring-cloud-dependencies</artifactId> 
      <version>${spring-cloud.version}</version> 
      <type>pom</type> 
      <scope>import</scope> 
     </dependency> 
    </dependencies> 
</dependencyManagement> 

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-maven-plugin</artifactId> 
     </plugin> 
    </plugins> 
</build> 

<repositories> 
    <repository> 
     <id>spring-snapshots</id> 
     <name>Spring Snapshots</name> 
     <url>https://repo.spring.io/snapshot</url> 
     <snapshots> 
      <enabled>true</enabled> 
     </snapshots> 
    </repository> 
    <repository> 
     <id>spring-milestones</id> 
     <name>Spring Milestones</name> 
     <url>https://repo.spring.io/milestone</url> 
     <snapshots> 
      <enabled>false</enabled> 
     </snapshots> 
    </repository> 
</repositories> 

봄 -boot 주요 클래스는 다음과 같습니다 : 다음과 같이

package com.oreilly.cloud; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.security.access.prepost.PreAuthorize; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 

@SpringBootApplication 
@EnableAuthorizationServer 
@EnableResourceServer 
@RestController 
@EnableGlobalMethodSecurity(prePostEnabled=true) 
public class SpringMicroservicesOauthServerApplication { 

    @RequestMapping("/resource/endpoint") 
    @PreAuthorize("hasRole('ADMIN')") 
    public String endpoint(){ 
     return "This message is protected by the resource server."; 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(SpringMicroservicesOauthServerApplication.class, args); 
    } 
} 

권한 부여 서버 구성은 다음과 같습니다

,369

package com.oreilly.cloud; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.authentication.AuthenticationManager; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 

@Configuration 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Bean 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication().withUser("user1").password("password1").roles("USER").and().withUser("admin") 
       .password("password2").roles("ADMIN"); 
    } 

} 
:이 상기 클래스로 자동 설정할 수 있도록 1,363,210
package com.oreilly.cloud; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.authentication.AuthenticationManager; 
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 

@Configuration 
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    private AuthenticationManager authManager; 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     endpoints.authenticationManager(authManager); 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.inMemory().withClient("webapp").secret("websecret").authorizedGrantTypes("password") 
       .scopes("read,write,trust"); 
    } 

} 

주 인증 관리자는 자동 권한 부여 설정 인증 관리자가 구성된 아래 클래스

으로 유선 및 abean로 반환

이제 application.properties은 다음과 같습니다 :

server.port=9090 

지금 내가 SP 실행 아래 링 부팅 응용 프로그램 :

MVN 스프링 부팅이 : 응용 프로그램이 성공적으로 시작하고 로컬 호스트의 포트 9090에 대한 요청을 받아 들일 준비가

을 실행

내가 얻을 수있는 POST 요청을 보내고 자 우편 배달부를 사용하여 access_token. 약간의 배경은 여기서 사용되는 Aoauth2 플로우가 비밀번호 부여입니다. 따라서 위의 AuthorizationServerConfig 클래스에서 암호 부여 흐름을 정의하고 클라이언트 이름과 암호가있는 간단한 웹 응용 프로그램을 등록했습니다. 클라이언트 구성이 메모리에 있음을 알 수 있습니다.

인증 서버로부터 액세스 토큰을 얻으려는 게시물 사용자 요청은 다음과 같습니다. 사용자 이름이 webapp이고 암호가 websecret 인 기본 인증 헤더 헤더가있는 게시물 요청입니다.

{ 
    "access_token": "2d632e54-17c3-41f7-af3b-935ca3022d78", 
    "token_type": "bearer", 
    "expires_in": 43199, 
    "scope": "read,write,trust" 
} 

을 이제 다음과 같이 내가 위의 액세스 토큰과 함께/RESOURSE/엔드 포인트에 액세스하려고하면 다음과 같이

http://localhost:9090/oauth/token?grant_type=password&username=user1&password=password1

이 요청은 액세스 토큰 JSON 성공적으로 반환

http://localhost:9090/resource/endpoint?access_token=2d632e54-17c3-41f7-af3b-935ca3022d78

service/resourse/endpoint에서 리턴 된 텍스트를 리턴하는 것이 아니라 그것은 다음과 같이 로그인 페이지 반환

<html> 
    <head> 
     <title>Login Page</title> 
    </head> 
    <body onload='document.f.username.focus();'> 
     <h3>Login with Username and Password</h3> 
     <form name='f' action='/login' method='POST'> 
      <table> 
       <tr> 
        <td>User:</td> 
        <td> 
         <input type='text' name='username' value=''> 
        </td> 
       </tr> 
       <tr> 
        <td>Password:</td> 
        <td> 
         <input type='password' name='password'/> 
        </td> 
       </tr> 
       <tr> 
        <td colspan='2'> 
         <input name="submit" type="submit" value="Login"/> 
        </td> 
       </tr> 
       <input name="_csrf" type="hidden" value="8dbc1c38-6f89-43c5-a8f8-797c920722a1" /> 
      </table> 
     </form> 
    </body> 
</html> 

사람이 내가 여기에 놓친 거지 무엇을 도와주세요 수를 ?????.

참고 동일한 응용 프로그램에서 권한 서버와 자원 서버를 모두 구성했습니다.이것은 POC이므로 봄 클라우드 보안을 시도하고 있습니다. 나중에 두 개를 분리 할 것입니다 ...하지만 나중에 사용합니다.

+0

정확히 무엇입니까? –

+1

토큰에 expires_in의 값이 재미있어 보입니다. 맵핑되는 대상은 분명히 틱이 아닙니다. 확인할 수 있습니까? –

+0

@WilliamHampshire 내 질문 : 클라이언트의 사용자 이름과 비밀번호를 지정하는 기본 인증 헤더가있는 http : // localhost : 9090/oauth/token? grant_type = password & username = admin & password = password2 위의 액세스 토큰으로 설정된 access_token 매개 변수로 보호 된 리소스 (/ resource/endpoint /)에 액세스하려고하면 내 끝점에서 반환해야하는 텍스트 응답 대신 로그인 페이지가 나타납니다. – santhoshbhatti

답변

1

스프링 부트의 루트 디버그 로그를 살펴봄으로써 문제를 발견했습니다.

당신이 yml를 사용하는 경우 :

src/main/resources/application.yml 
---------------------------------- 
logging: 
    level: 
    root: DEBUG 

또는 경우 properties을 :

src/main/resources/application.properties 
---------------------------------- 
logging.level.root=DEBUG 

나는 내가 GET와 사용자의 인증 정보를 전달되지 않았다 실현을 :

o.s.s.w.a.ExceptionTranslationFilter: Access is denied (user is anonymous); ... 

2 가지 중 하나를 할 수 있습니다 :

1. url 매개 변수를 통해 cred를 추가하십시오 (예 :
curl -X GET \ 
    'http://localhost:9090/resource/endpoint? 
    username=user1&password=password1&access_token=xxxx' 

또는

는 예를 들어, 인증의 기본을 통해 creds를 추가합니다.
curl -X GET \ 
    'http://localhost:9090/resource/endpoint?username=user1' \ 
    -H 'Authorization: Basic xxxxxxxxxxxxx 

당신도 safaribooksonline에 봄 과정으로 떨어져 건물 Microservices이나요? :)

나는 교사가 문제가 없었던 이유를 발견했다. 그는 이전에 사용자 이름/암호를 승인 했음에 틀림 없습니다. GET 이후에 리소스를 한 번만 입력하면 auth_token으로 다시 호출하면 어딘가에 캐시 된 것으로 보입니다.

관련 문제