Ich versuche, mich mit OAuth2 und Spring Security OAuth zu beschäftigen, insbesondere mit dem OAuth Provider-Service. Ich versuche Folgendes zu implementieren:
Alle diese Module sind unabhängig voneinander, dh in verschiedenen Projekten getrennt und werden in verschiedenen Domänen gehostet, z. B. (1) http://oauth.web.com , (2) http://rest.web.com , (3) http://web.com
Meine zwei Fragen sind:
A. Wie implementiere ich ein Webclient-Projekt, damit Benutzer, die sich auf der geschützten Seite anmelden oder auf die Schaltfläche Anmelden klicken, zur OAuth-Provider-URL umgeleitet, angemeldet und auf dem Webclient mit allen Benutzerrollen und auch authentifiziert werden Sie müssen auch wissen, welcher Client verwendet wurde. @EnableResourceServer
(auf die gleiche Weise, wie Resource Server implementiert ist; siehe Code unten) in diesem Projekt, um Benutzerdetails zu erhalten? Muss ich Access Token verwalten und immer in den Aufruf des Ressourcenservers einbeziehen, oder kann dies irgendwie automatisch erfolgen?
B. Was ist der beste Weg, um Sicherheit auf den mobilen Apps zu implementieren, die ich entwickeln werde? Sollte ich für diese Authentifizierung das Passwort grand verwenden, da die Apps von mir erstellt werden, wobei ein Benutzername und ein Passwort im nativen Bildschirm angezeigt werden und dann als Basisauthentifizierung über SSL an den Server gesendet werden? Gibt es Beispiele, die ich mir in diesem Gespräch mit Spring Security OAuth ansehen und Benutzerdetails zurückgeben kann?
Hier ist meine Implementierung von OAuth Project (1) und Resource Project (2):
OAuth2 Server Configs (der größte Teil des Codes wurde HIER übernommen )
@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
DataSource dataSource;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore())
.approvalStore(approvalStore())
.authorizationCodeServices(authorizationCodeServices())
;
}
@Bean
public JdbcClientDetailsService clientDetailsService() {
return new JdbcClientDetailsService(dataSource);
}
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean
public ApprovalStore approvalStore() {
return new JdbcApprovalStore(dataSource);
}
@Bean
public AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.checkTokenAccess("permitAll()");
}
}
Web Security Config
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); // TODO. Enable this!!!
http.authorizeRequests()
.and()
.formLogin()
// .loginPage("/login") // manually defining page to login
// .failureUrl("/login?error") // manually defining page for login error
.usernameParameter("email")
.permitAll()
.and()
.logout()
// .logoutUrl("/logout")
.logoutSuccessUrl("/")
.permitAll();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(customUserDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
UserDetailsService (customUserDetailsService)
@Service
public class CustomUserDetailsService implements UserDetailsService{
private final UserService userService;
@Autowired
public CustomUserDetailsService(UserService userService) {
this.userService = userService;
}
public Authority loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userService.getByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException(String.format("User with email=%s was not found", email)));
return new Authority(user);
}
}
Konfiguration (der größte Teil des Skelettcodes stammt aus DIESEM Beispiel)
@Configuration
@EnableResourceServer
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter{
@Autowired
DataSource dataSource;
String RESOURCE_ID = "data_resource";
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
TokenStore tokenStore = new JdbcTokenStore(dataSource);
resources
.resourceId(RESOURCE_ID)
.tokenStore(tokenStore);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
// For some reason we cant just "permitAll" OPTIONS requests which are needed for CORS support. Spring Security
// will respond with an HTTP 401 nonetheless.
// So we just put all other requests types under OAuth control and exclude OPTIONS.
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
.antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')")
.and()
// Add headers required for CORS requests.
.headers().addHeaderWriter((request, response) -> {
response.addHeader("Access-Control-Allow-Origin", "*");
if (request.getMethod().equals("OPTIONS")) {
response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method"));
response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
}
});
}
}
WS Controller:
@RestController
@RequestMapping(value = "/todos")
public class TodoController {
@Autowired
private TodoRepository todoRepository;
@RequestMapping(method = RequestMethod.GET)
public List<Todo> todos() {
return todoRepository.findAll();
}
// other methods
}
Wie implementiere ich ein Webclient-Projekt, damit Benutzer, die sich auf der geschützten Seite anmelden oder auf die Schaltfläche Anmelden klicken, zur OAuth-Provider-URL umgeleitet werden, sich anmelden und auf dem Webclient mit allen Benutzerrollen und auch authentifiziert werden müssen wissen, welcher Client verwendet wurde
Sie möchten OAuth als SSO verwenden.
Option 1: Verwenden Sie die Frühlingswolke https://spring.io/blog/2015/02/03/sso-with-oauth2-angular-js-and-spring-security-part-v
Option 2: SSO-Prozess manuell abwickeln:
Konfigurieren Sie in Ihrem Webclient die Anmeldeseite für den OAuth-Server mithilfe der Berechtigungsgewährung.
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); // TODO. Enable this!!!
http.authorizeRequests()
.and()
.formLogin()
.loginPage("http://oauth.web.com/oauth/authorize?response_type=code&client_id=webclient&redirect_uri=http://web.com") // manually defining page to login
//.failureUrl("/login?error") // manually defining page for login error
.usernameParameter("email")
.permitAll()
.and()
.logout()
//.logoutUrl("/logout")
.logoutSuccessUrl("/")
.permitAll();
}
Nach Abschluss des Authentifizierungs- und Autorisierungsprozesses werden Sie mit dem Autorisierungscode zum Webclient weitergeleitet http://web.com/?code=jYWioI
. Ihr Webclient sollte diesen Code mit Tokenzugriff auf Ihrem oauth-Server austauschen. Erstellen Sie auf Ihrem oauth-Server einen Endpunkt zum Abrufen von Benutzerinformationen
@RestController
public class UserRestService {
@RequestMapping("/user")
public Principal user(Principal user) {
// you can also return User object with it's roles
// {"details":...,"principal":{"username":"user",...},"name":"user"}
return user;
}
}
Anschließend kann Ihr Webclient auf die Benutzerdetails zugreifen, indem er eine Anforderung mit dem Tokenzugriff an den oben genannten Restendpunkt sendet und den Benutzer anhand der Antwort authentifiziert.
Muss ich Access Token verwalten und immer in den Aufruf des Ressourcenservers einbeziehen, oder kann dies irgendwie automatisch erfolgen?
Jede Anfrage muss einen Token-Zugriff enthalten. Wenn Sie dies automatisch tun möchten, hat spring den Oauth 2-Client http://projects.spring.io/spring-security-oauth/docs/oauth2.html bereitgestellt
Was ist der beste Weg, um Sicherheit auf den mobilen Apps zu implementieren, die ich entwickeln werde? Sollte ich für diese Authentifizierung das Passwort grand verwenden, da die Apps von mir erstellt werden, wobei ein Benutzername und ein Passwort im nativen Bildschirm angezeigt werden und dann als Basisauthentifizierung über SSL an den Server gesendet werden?
Da Sie den nativen Bildschirm verwenden, reicht die Kennwortgewährung aus, aber Sie können das Aktualisierungstoken speichern. Auf diese Weise können Sie den Tokenzugriff anfordern, ohne den Authentifizierungsprozess zu wiederholen.
Gibt es Beispiele, die ich mir in diesem Gespräch mit Spring Security OAuth ansehen und Benutzerdetails zurückgeben kann?
Sehen Sie sich den obigen Beispielcode an oder sehen Sie sich diesen https://spring.io/blog/2015/02/03/sso-with-oauth2-angular-js-and-spring-security-part-v an
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen