Я реализовал сущность User с CustomUserDetailService, до аутентификации все работает хорошо. Когда я пытался настроить oauth2 для авторизации клиентов. Код работал хорошо для деталей клиента InMemory. Проблема возникла, когда я попытался добавить источник данных JDB c для деталей клиента. Класс сущности для oauth_client_details приведен ниже:
package com.meganos.app.security.auth;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name="oauth_client_details")
public class OauthClientDetails {
@Id
@Column(name="client_id")
private String clientId;
@Column(name="resource_ids")
private String resourceIds;
@Column(name="client_secret")
private String clientSecret;
@Column(name="scope")
private String scope;
@Column(name="authorized_grant_types")
private String authorizedGrantTypes;
@Column(name="web_server_redirect_uri")
private String webServerRedirectUri;
@Column(name="authorities")
private String authorities;
@Column(name="access_token_validity", length=11)
private Integer accessTokenValidity;
@Column(name="refresh_token_validity", length=11)
private Integer refreshTokenValidity;
@Column(name="additional_information", length=4096)
private String additionalInformation;
@Column(name="autoapprove", columnDefinition = "TINYINT(4)")
private String autoapprove;
@Column(name="uuid")
private String uuid;
@Column
private Date created;
@Column(columnDefinition ="boolean default true")
private Boolean enabled;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getResourceIds() {
return resourceIds;
}
public void setResourceIds(String resourceIds) {
this.resourceIds = resourceIds;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getAuthorizedGrantTypes() {
return authorizedGrantTypes;
}
public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
this.authorizedGrantTypes = authorizedGrantTypes;
}
public String getWebServerRedirectUri() {
return webServerRedirectUri;
}
public void setWebServerRedirectUri(String webServerRedirectUri) {
this.webServerRedirectUri = webServerRedirectUri;
}
public String getAuthorities() {
return authorities;
}
public void setAuthorities(String authorities) {
this.authorities = authorities;
}
public Integer getAccessTokenValidity() {
return accessTokenValidity;
}
public void setAccessTokenValidity(Integer accessTokenValidity) {
this.accessTokenValidity = accessTokenValidity;
}
public Integer getRefreshTokenValidity() {
return refreshTokenValidity;
}
public void setRefreshTokenValidity(Integer refreshTokenValidity) {
this.refreshTokenValidity = refreshTokenValidity;
}
public String getAdditionalInformation() {
return additionalInformation;
}
public void setAdditionalInformation(String additionalInformation) {
this.additionalInformation = additionalInformation;
}
public String getAutoapprove() {
return autoapprove;
}
public void setAutoapprove(String autoapprove) {
this.autoapprove = autoapprove;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
}
Код класса моего сервера авторизации находится здесь:
package com.meganos.app.security.config;
import com.meganos.app.security.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
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.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import javax.sql.DataSource;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.passwordEncoder(NoOpPasswordEncoder.getInstance())
.checkTokenAccess("permitAll()")
.tokenKeyAccess("permitAll()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource)
// .inMemory()
.withClient("admin_app")
.secret("secret")
.scopes("1")
.autoApprove(true)
.authorizedGrantTypes("password","authorization_code", "refresh_token", "client_credentials")
.resourceIds()
.and()
.build();
// JdbcClientDetailsService jdbcClientDetailsService=new JdbcClientDetailsService(dataSource);
// clients.withClientDetails(jdbcClientDetailsService);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
// .approvalStoreDisabled()
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
У меня возникают следующие проблемы:
- Первая и главная проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь использовать
clients.inMemory().withClients()..
при настройке ClientDetailsServiceConfigurer, он работает гладко, он хорошо генерирует токен и справедливо авторизует запросы. Но когда я попытался добавить clients.jdbc(datasource).withClients()..
и попытался сгенерировать токен, используя Почтальон, как показано:
с базой c oauth с использованием введенных данных клиента в построении клиента детали: , если дает несанкционированный доступ к этому URL, как это:
{
"timestamp": "2020-05-04T08:21:09.223+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/oauth/token"
}
Вторая проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытался ввести область действия в какой-либо строковой форме, такой как (чтение, запись) как:
clients.jdb c (dataSource) .inMemory () .withClient ("admin_app") .secret ("secret") .scopes ("read") .autoApprove (true) .authorizedGrantTypes ("пароль", "код авторизации", "refresh_token", "" client_credentials ") .resourceIds () .and () .build ();
выдает следующую ошибку при сборке клиентов и сохранении в базе данных:
Data conversion error converting "'read' (OAUTH_CLIENT_DETAILS: ""AUTOAPPROVE"" TINYINT)"; SQL statement:
Код моего класса AuthenticationServerConfig приведен ниже:
package com.meganos.app.security.config;
import com.meganos.app.security.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AuthenticationServerConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Bean
public DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider authenticationProvider=new DaoAuthenticationProvider();
authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder(11));
authenticationProvider.setUserDetailsService(customUserDetailsService);
authenticationProvider.setAuthoritiesMapper(grantedAuthoritiesMapper());
return authenticationProvider;
}
@Bean
public GrantedAuthoritiesMapper grantedAuthoritiesMapper(){
SimpleAuthorityMapper authorityMapper=new SimpleAuthorityMapper();
authorityMapper.setConvertToUpperCase(true);
authorityMapper.setDefaultAuthority("USER");
return authorityMapper;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.logout().invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.ignoring()
.antMatchers("/", "/index", "/css/*", "/js/*", "/test/unsecured", "/oauth/token/*")
.antMatchers("/h2-console", "/h2-console/*");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Я видел много вопросов, подобных этому, в stackoverflow и пытался решить свои проблемы, используя их, но я не получил положительного ответа после попытки всего. Я ищу руководство для экспертов, заранее спасибо.