Можно ли получить токен доступа с контроллера того же сервера? - PullRequest
1 голос
/ 01 августа 2020

Я реализовал безопасность Sprint oauth2. Когда я использую curl, я получаю токен доступа.

Я сомневаюсь, можно ли сгенерировать токен доступа с помощью метода контроллера? т.е. когда я вызываю логин, я передаю имя пользователя и пароль внутри метода входа контроллера, я хотел бы получить токен доступа с помощью RestTemplate. Это означает, что я вызову URL-адрес oauth для того же сервера с необходимыми параметрами, и я хотел бы получить токен доступа для доступа к остальным ресурсам в качестве ответа на мой вызов входа в систему.

Например,

  • Я позвоню http://localhost: 8080 / user / login
  • Метод внутреннего контроллера для / user / login, я получу свой токен доступа, используя URL-адрес oauth и параметры
  • I вернет токен доступа в качестве ответа на мой вызов входа
  • Я буду использовать этот токен доступа для остальной части защищенного API.

Когда я попробовал это, он показывает неавторизованный (401 ) ошибка для URL-адреса / oauth / token.

Итак, можно ли сделать так, кто-нибудь уже пробовал это?

Пожалуйста, помогите мне.

Заранее спасибо .

Привет, пожалуйста, найдите мои коды ниже. Я использую порт 8081

Контроллер

 @PostMapping("/user/login")
public User login(@RequestBody User user) {

    ResponseEntity<String> response =null;

    RestTemplate template = new RestTemplate();
    String credentials = "client:secret";
    String credentialsEnc = new String(Base64.encodeBase64(credentials.getBytes()));

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    

    HttpEntity<String> request = new HttpEntity<>(headers);
    Map<String, String> uriVars = new HashMap<String, String>();
    uriVars.put("username", "user1");
    uriVars.put("password", "password");
    uriVars.put("grant_type", "password");
    uriVars.put("scope", "read");

    String accessTokenUrl = "http://localhost:8081/oauth/token";
        response = template.exchange(accessTokenUrl, HttpMethod.POST, request, String.class, uriVars);
    
    System.out.println("Access Token response-" +response);

    System.out.println("Authorization code-->" +response);

    return user;
}


@Configuration
@EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {

@Override
public void configure(ResourceServerSecurityConfigurer 
serverSecurityConfigurer) {
    serverSecurityConfigurer.resourceId("api");
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .antMatcher("/api/**")
            .authorizeRequests()
            .antMatchers("/user**").permitAll()
            .antMatchers("/user/**").permitAll()
            .antMatchers("/admin**").hasAuthority("ADMIN")
            .antMatchers("/api/**").authenticated()
            .and().authorizeRequests().anyRequest().access("#oauth2.hasScope('read')");
            
}
}


@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends 
AuthorizationServerConfigurerAdapter {

private final AuthenticationManager authenticationManager;
private final PasswordEncoder passwordEncoder;
private final UserDetailsService userDetailsService;

@Value("${jwt.clientId:client}")
private String clientId;

@Value("${jwt.client-secret:secret}")
private String clientSecret;

@Value("${jwt.signing-key:123}")
private String jwtSigningKey;

@Value("${jwt.accessTokenValidititySeconds:43200}") // 12 hours
private int accessTokenValiditySeconds;

@Value("${jwt.authorizedGrantTypes:password,authorization_code,refresh_token}")
private String[] authorizedGrantTypes;

@Value("${jwt.refreshTokenValiditySeconds:2592000}") // 30 days
private int refreshTokenValiditySeconds;

public AuthorizationServerConfig(AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder,
                                 UserDetailsService userDetailsService) {
    this.authenticationManager = authenticationManager;
    this.passwordEncoder = passwordEncoder;
    this.userDetailsService = userDetailsService;
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
            .withClient(clientId)
            .secret(passwordEncoder.encode(clientSecret))
            .accessTokenValiditySeconds(accessTokenValiditySeconds)
            .refreshTokenValiditySeconds(refreshTokenValiditySeconds)
            .authorizedGrantTypes(authorizedGrantTypes)
            .authorities("ROLE_ADMIN")
            .scopes("read", "write")
            .resourceIds("api");
}


@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
    endpoints
            .accessTokenConverter(accessTokenConverter())
            .userDetailsService(userDetailsService)
            .authenticationManager(authenticationManager);
}

@Bean
JwtAccessTokenConverter accessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    return converter;
}
}


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
DataSource dataSource;

@Autowired
UserDetailsService userDetailsService;

public SecurityConfig(UserDetailsService userDetailsService) {
    this.userDetailsService =userDetailsService;
}

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setPasswordEncoder(passwordEncoder());
    provider.setUserDetailsService(userDetailsService);
    return provider;
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests().
            antMatchers(HttpMethod.POST, "/user/**").permitAll().
            antMatchers(HttpMethod.POST,"/admin/**").hasAnyRole("ADMIN").
            anyRequest().authenticated();

}

@Override
public void configure(AuthenticationManagerBuilder builder) throws Exception{
    builder.jdbcAuthentication().dataSource(dataSource)
            .usersByUsernameQuery("select usrnam,usrpwd, case when usrsta='A' then true else false end from usrmst where usrnam=?")
            .authoritiesByUsernameQuery("select usrnam,usrtyp from usrmst where usrnam=?");
}

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

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();

}

}

Ответы [ 2 ]

0 голосов
/ 02 августа 2020

Я нашел решение. Использовал метод POST, передав параметры в url без переменных uri, он заработал.

Спасибо ..

0 голосов
/ 01 августа 2020

Вы можете получить token, используя OAuth2RestTemplate на том же сервере

private OAuth2AccessToken getToken(LoginResource loginResource) {
    String access_token_url = "http://localhost:8081/api/oauth/token";
    ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
    resourceDetails.setGrantType("password");
    resourceDetails.setAccessTokenUri(access_token_url);
    
        //-- set the clients info
    resourceDetails.setClientId("client_id");
    resourceDetails.setClientSecret("client_secret");
        
        // set scopes
    List<String> scopes = new ArrayList<>();
    scopes.add("read"); 
    scopes.add("write");
    scopes.add("trust");
    resourceDetails.setScope(scopes);
        
    //-- set Resource Owner info
    resourceDetails.setUsername(loginResource.getUserName());
    resourceDetails.setPassword(loginResource.getPassword());
    OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(resourceDetails);
    return oAuth2RestTemplate.getAccessToken(); 
}
...