Oauth2 bad Anmeldeinformationen Spring Boot
Bin ich immer die Fehlermeldung:
"error": "invalid_grant",
"error_description": "Bad credentials"
Hier ist die Anforderung, die ich machen:
POST /oauth/token HTTP/1.1
Host: localhost:8443
Authorization: Basic bW9iaWxlOg==
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
username=admin&password=pass&client_id=mobile&grant_type=password&client_secret=
Mein code ist von hier: https://github.com/juleswhite/mobilecloud-14/tree/master/examples/9-VideoServiceWithOauth2
Hier ist der code:
Application.java:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.capstone.auth.OAuth2SecurityConfiguration;
import com.google.common.io.BaseEncoding;
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableWebMvc
@Import(OAuth2SecurityConfiguration.class)
public class Application extends RepositoryRestMvcConfiguration{
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
ClientAndUserDetailsService.java
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService;
/**
* A class that combines a UserDetailsService and ClientDetailsService
* into a single object.
*
* @author jules
*
*/
public class ClientAndUserDetailsService implements UserDetailsService,
ClientDetailsService {
private final ClientDetailsService clients_;
private final UserDetailsService users_;
private final ClientDetailsUserDetailsService clientDetailsWrapper_;
public ClientAndUserDetailsService(ClientDetailsService clients,
UserDetailsService users) {
super();
clients_ = clients;
users_ = users;
clientDetailsWrapper_ = new ClientDetailsUserDetailsService(clients_);
}
@Override
public ClientDetails loadClientByClientId(String clientId)
throws ClientRegistrationException {
return clients_.loadClientByClientId(clientId);
}
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
UserDetails user = null;
try{
user = users_.loadUserByUsername(username);
}catch(UsernameNotFoundException e){
user = clientDetailsWrapper_.loadUserByUsername(username);
}
return user;
}
}
OAuth2SecurityConfiguration.java
@Configuration
public class OAuth2SecurityConfiguration {
//This first section of the configuration just makes sure that Spring
//Security picks
//up the UserDetailsService that we create below.
@Configuration
@EnableWebSecurity
protected static class WebSecurityConfiguration extends
WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
protected void registerAuthentication(
final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
}
/**
* This method is used to configure who is allowed to access which parts of
* our resource server (i.e. the "/video" endpoint)
*/
@Configuration
@EnableResourceServer
protected static class ResourceServer extends
ResourceServerConfigurerAdapter {
//This method configures the OAuth scopes required by clients to access
//all of the paths in the video service.
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/oauth/token").anonymous();
//If you were going to reuse this class in another
//application, this is one of the key sections that you
//would want to change
//Require all GET requests to have client "read" scope
http.authorizeRequests().antMatchers(HttpMethod.GET, "/**")
.access("#oauth2.hasScope('read')");
//Require all other requests to have "write" scope
http.authorizeRequests().antMatchers("/**")
.access("#oauth2.hasScope('write')");
}
}
/**
* This class is used to configure how our authorization server (the
* "/oauth/token" endpoint) validates client credentials.
*/
@Configuration
@EnableAuthorizationServer
@Order(Ordered.LOWEST_PRECEDENCE - 100)
protected static class OAuth2Config extends
AuthorizationServerConfigurerAdapter {
//Delegate the processing of Authentication requests to the framework
@Autowired
private AuthenticationManager authenticationManager;
//A data structure used to store both a ClientDetailsService and a
//UserDetailsService
private ClientAndUserDetailsService combinedService_;
/**
*
* This constructor is used to setup the clients and users that will be
* able to login to the system. This is a VERY insecure setup that is
* using hard-coded lists of clients /users /passwords and should
* never be used for anything other than local testing on a machine that
* is not accessible via the Internet. Even if you use this code for
* testing, at the bare minimum, you should consider changing the
* passwords listed below and updating the VideoSvcClientApiTest.
*
* @param auth
* @throws Exception
*/
public OAuth2Config() throws Exception {
//If you were going to reuse this class in another
//application, this is one of the key sections that you
//would want to change
//Create a service that has the credentials for all our clients
ClientDetailsService csvc = new InMemoryClientDetailsServiceBuilder()
//Create a client that has "read" and "write" access to the
//video service
.withClient("mobile")
.authorizedGrantTypes("password")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write")
.resourceIds("test")
.and()
//Create a second client that only has "read" access to the
//video service
.withClient("mobileReader")
.authorizedGrantTypes("password")
.authorities("ROLE_CLIENT").scopes("read")
.resourceIds("test").accessTokenValiditySeconds(3600)
.and().build();
//Create a series of hard-coded users.
UserDetailsService svc = new InMemoryUserDetailsManager(
Arrays.asList(
User.create("admin", "pass", "ADMIN", "USER"),
User.create("user0", "pass", "USER"),
User.create("username", "password", "USER")));
//Since clients have to use BASIC authentication with the client's
//id/secret,
//when sending a request for a password grant, we make each client
//a user
//as well. When the BASIC authentication information is pulled from
//the
//request, this combined UserDetailsService will authenticate that
//the
//client is a valid "user".
combinedService_ = new ClientAndUserDetailsService(csvc, svc);
}
/**
* Return the list of trusted client information to anyone who asks for
* it.
*/
@Bean
public ClientDetailsService clientDetailsService() throws Exception {
return combinedService_;
}
/**
* Return all of our user information to anyone in the framework who
* requests it.
*/
@Bean
public UserDetailsService userDetailsService() {
return combinedService_;
}
/**
* This method tells our AuthorizationServerConfigurerAdapter to use the
* delegated AuthenticationManager to process authentication requests.
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager);
}
/**
* This method tells the AuthorizationServerConfigurerAdapter to use our
* self-defined client details service to authenticate clients with.
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.withClientDetails(clientDetailsService());
}
}
//This version uses the Tomcat web container and configures it to
//support HTTPS. The code below performs the configuration of Tomcat
//for HTTPS. Each web container has a different API for configuring
//HTTPS.
//
//The app now requires that you pass the location of the keystore and
//the password for your private key that you would like to setup HTTPS
//with. In Eclipse, you can set these options by going to:
//1. Run->Run Configurations
//2. Under Java Applications, select your run configuration for this app
//3. Open the Arguments tab
//4. In VM Arguments, provide the following information to use the
//default keystore provided with the sample code:
//
//-Dkeystore.file=src/main/resources/private/keystore
//-Dkeystore.pass=changeit
//
//5. Note, this keystore is highly insecure! If you want more securtiy, you
//should obtain a real SSL certificate:
//
//http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
//
@Bean
EmbeddedServletContainerCustomizer containerCustomizer(
@Value("${keystore.file:src/main/resources/private/keystore}") String keystoreFile,
@Value("${keystore.pass:changeit}") final String keystorePass)
throws Exception {
//If you were going to reuse this class in another
//application, this is one of the key sections that you
//would want to change
final String absoluteKeystoreFile = new File(keystoreFile)
.getAbsolutePath();
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container;
tomcat.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
connector.setPort(8443);
connector.setSecure(true);
connector.setScheme("https");
Http11NioProtocol proto = (Http11NioProtocol) connector
.getProtocolHandler();
proto.setSSLEnabled(true);
proto.setKeystoreFile(absoluteKeystoreFile);
proto.setKeystorePass(keystorePass);
proto.setKeystoreType("JKS");
proto.setKeyAlias("tomcat");
}
});
}
};
}
}
Vielen Dank für Ihre Aufmerksamkeit und Zeit!
Diese
Nein, ich habe nicht gefragt! Aber Ι schweigen von der Quelle des Codes. Es ist falsch?
OK, vielen Dank. Ich wusste nicht, ob das war Ihr code oder die Quelle von allen anderen komisch authentication manager.
Das sieht hinky zu:
Ok danke, werde ich mit der Feder OAuth-tests (Beispiel)!
ClientAndUserDetailsService
sieht aus wie ein anti-pattern, und ich habe gesehen, dass es ziemlich viel in letzter Zeit. Haben Sie Fragen zu dieser vor, sind Sie nur kopieren von code aus dem gleichen Ort (wo)?Nein, ich habe nicht gefragt! Aber Ι schweigen von der Quelle des Codes. Es ist falsch?
OK, vielen Dank. Ich wusste nicht, ob das war Ihr code oder die Quelle von allen anderen komisch authentication manager.
Das sieht hinky zu:
http.authorizeRequests().antMatchers("/oauth/token").anonymous()
. Ich würde vielleicht empfehlen abschreiben aus der Feder OAuth-tests (Beispiel) anstatt von jules, wenn Sie wollen etwas, das Sie kopieren und einfügen können.Ok danke, werde ich mit der Feder OAuth-tests (Beispiel)!
InformationsquelleAutor KostasC | 2014-10-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kurze Antwort: können Sie nicht
@Autowired
eineAuthenticationManager
in eineAuthorizationServerConfigurerAdapter
wenn Sie mit Spring Boot (noch) nicht.Lange anwswer: dieses Beispiel funktioniert, weil es doch autowires die
AuthenticationManagerBuilder
statt, und erstellt ein lazy-init-version desAuthenticationManager
für die token rechtsvorgängers zu verwenden. Mit dem Frühling OAuth2 2.0.3 Sie erstellen müssen, die faulAuthenticationManager
sich (wie diese:Mit Schnappschüssen (oder 2.0.4, wenn es freigegeben wird), können Sie einfach die neue überladene Methode in
AuthorizationServerConfigurerAdapter
.Ich fand, was war mein Fehler in meinem build.gradle-Datei ich war mit springBootVersion = '1.1.8.RELEASE' und ändere ich es auf 1.0.2.RELEASE' - und es funktioniert! Vielen Dank für Ihre Zeit, Dave Syer.
Das ist nicht wirklich ein fix, es ist nur noch zu verschieben, das problem. Interessant, dass es arbeitete in 1.0.2 obwohl.
was bedeutet u "bedeutet" Sie können einfach verwenden Sie die neue überladene Methode in AuthorizationServerConfigurerAdapter"
Sie Jungs haben zu lernen von spring data-team, wie die Dinge zu vereinfachen!
InformationsquelleAutor Dave Syer