【发布时间】:2020-08-01 06:49:50
【问题描述】:
我已经实现了 Sprint oauth2 安全性。当我使用 curl 时,我得到了访问令牌。
我的疑问是,是否可以在 Controller 方法中生成访问令牌? 即当我调用登录时,我将传递用户名和密码,在控制器登录方法中,我想通过使用 RestTemplate 获取访问令牌。意味着我将使用所需参数调用同一服务器的 oauth url,并且我想获取访问令牌以访问其余资源作为我登录调用的响应。
例如,
- 我会调用http://localhost:8080/user/login
- 在 /user/login 的控制器方法中,我将使用 oauth url 和参数获取我的访问令牌
- 我将返回访问令牌作为登录调用的响应
- 我会将该访问令牌用于其他安全 API。
当我尝试这个时,它显示 /oauth/token url 的未授权 (401) 错误。
那么有没有可能这样做,有人已经尝试过吗?
请帮帮我。
提前致谢。
嗨, 请在下面找到我的代码。我使用的是 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();
}
}
【问题讨论】:
-
是的,您可以点击令牌端点来获取访问令牌。您将哪些属性传递给令牌端点? Spring Security 配置文件中是否排除了这些端点?
-
您需要分享通话详情和spring安全配置以获取更多信息。
-
嗨,哈利,我已经分享了详细信息
标签: spring-boot spring-security oauth-2.0