如何解决在Spring Boot Oauth 2.0中成功接收到access_token的请求时,无法访问获得401 Unauthorized错误的资源
我正在使用带有Grant_type = authorization_code流的spring boot Oauth2安全性。
我已经成功接收到具有oauth / authorize请求的代码响应,然后将此代码传递给oauth / token请求,并且还成功接收了access_token作为响应。
现在,我想使用请求映射/ admin / 调用API,这会给我错误401未经授权。我已经向任何ROLE_ADMIN提供了对此(/ admin / )URL的访问权限。但是它会忽略还是不起作用。
在屏幕之后,我终于在这里给出了所有配置。
当我向邮递员请求/ admin / getData时,它将引发401未经授权的错误。
在这里,我将逐步发布邮递员的所有屏幕快照,请注意,因为它是localhost,在使用oauth / authorize获得代码值后,我已手动要求邮递员请求oauth /令牌。 / p>
第1步获取包含详细信息的新访问令牌
第2步获得了用于身份验证的登录表单
第3步收到的响应代码
第4步,请求具有相同代码和状态值的oauth /令牌,并成功接收具有其他值的访问令牌
第5步,请求控制器URL / admin / api / getData的访问令牌作为承载RECEIVED_ACCESS_TOKEN传递到标头中,出现401未经授权的错误
我正在使用ClientDetailService表单数据库身份验证。我完整的代码如下。
为WebSecurityConfigurerAdapter配置
@Configuration
@EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationService authenticationService;
@Autowired
private PasswordEncoder passwordEncoder;
@Bean(name = "myAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(authenticationService).passwordEncoder(passwordEncoder);
}
}
为ResourceServerConfigurerAdapter配置
@Configuration
@EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
// Open access to all
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS,"/oauth/authorize","/login","/oauth/token","/oauth/logout")
.permitAll();
http.formLogin().permitAll().and().logout().permitAll();
// Access to Admin
http.authorizeRequests().antMatchers("/admin/**").hasAuthority("ADMIN");
// All other request are authenticated
http.authorizeRequests().anyRequest().authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("resource_id").tokenStore(tokenStore).stateless(false);
}
}
配置AuthorizationServerConfigurerAdapter
@Configuration
@EnableAuthorizationServer
public class OAuth2Server extends AuthorizationServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
public AuthenticationManager authenticationManager;
@Autowired
private AuthenticationService authenticationService;
@Autowired
private DynamicClientDetailService dynamicClientDetailService;
@Autowired
private TokenEnhancer tokenEnhancer;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).tokenEnhancer(tokenEnhancer)
.userDetailsService(authenticationService).setClientDetailsService(dynamicClientDetailService);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(dynamicClientDetailService);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
}
为ClientDetailsService配置
@Configuration
public class DynamicClientDetailService implements ClientDetailsService {
@Autowired
private DynamicClientDetailsRepository dynamicClientDetailsRepository;
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
DynamicClientDetails client = dynamicClientDetailsRepository.findByClientId(clientId);
BaseClientDetails base = new BaseClientDetails(client.getClientId(),client.getResourceIds(),client.getScope(),client.getAuthorizedGrantTypes(),client.getAuthorities());
base.setClientSecret(client.getClientSecret());
base.setAccessTokenValiditySeconds(client.getAccessTokenValiditySeconds());
base.setRefreshTokenValiditySeconds(client.getRefreshTokenValiditySeconds());
base.setAutoApproveScopes(getScopes(client.getScope()));
base.setRegisteredRedirectUri(getRegisteredRedirectURL(client));
return base;
}
/**
* Get registered redirect URL
*
* @param client
* @return
*/
private Set<String> getRegisteredRedirectURL(DynamicClientDetails client) {
return StringUtils.isEmpty(client.getRegisteredRedirectUri()) ? null
: Arrays.stream(client.getRegisteredRedirectUri().split(",")).collect(Collectors.toSet());
}
/**
* Get collection from string
*
* @param scope
* @return
*/
private Collection<String> getScopes(String scope) {
Collection<String> scopes = new ArrayList<String>();
if (StringUtils.isEmpty(scope))
return scopes;
String[] scopesArr = scope.split(",");
if (scopesArr.length == 0)
return scopes;
scopes = Arrays.asList(scopesArr);
return scopes;
}
}
配置UserDetailsService
@Configuration
public class AuthenticationService implements UserDetailsService {
@Autowired
private LoginCredentialService loginCredentialService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LoginCredential loginCredential = loginCredentialService.getLoginCredentialByEmail(username);
return new org.springframework.security.core.userdetails.User(loginCredential.getEmail(),loginCredential.getPassword(),loginCredential.getIsActive(),!loginCredential.getIsDelete(),loginCredential.isVerified(),true,getSimpleGrantedAuthorities(loginCredential.getRole().toString()));
}
private Collection<GrantedAuthority> getSimpleGrantedAuthorities(String role) {
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
grantedAuthorities.add(new SimpleGrantedAuthority(role));
return grantedAuthorities;
}
}
控制器代码
@RestController
@RequestMapping("/admin/api")
public class DataController {
@GetMapping("/getData")
public ResponseEntity<String> getData() throws Exception {
return ResponseEntity.ok("Success");
}
}
为客户详细信息创建查询
CREATE TABLE public.dynamic_client_details
(
id bigint NOT NULL DEFAULT nextval('dynamic_client_details_id_seq'::regclass),access_token_validity_seconds integer,authorities character varying(255),authorized_grant_types character varying(255),auto_approve boolean NOT NULL,client_id character varying(255),client_secret character varying(255),refresh_token_validity_seconds integer,registered_redirect_uri character varying(255),resource_ids character varying(255),scope character varying(255),scoped boolean NOT NULL,secret_required boolean NOT NULL,CONSTRAINT dynamic_client_details_pkey PRIMARY KEY (id),);
插入查询带有值的客户详细信息
INSERT INTO public.dynamic_client_details(id,access_token_validity_seconds,authorities,authorized_grant_types,auto_approve,client_id,client_secret,refresh_token_validity_seconds,registered_redirect_uri,resource_ids,scope,scoped,secret_required)
VALUES (1,50000,'ROLE_ADMIN','password,authorization_code,refresh_token','MY_CLIENT_ID','MY_ENCODED_SECRET','https://oauth.pstmn.io/v1/callback','resource_id','read,write,trust',true);
具有IN DB登录表角色的用户详细信息
email = abc@gmail.com
password = MY_PASSWORD
role = ROLE_ADMIN
请指导我如何更改授权用户的API。
谢谢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。