Reputation: 37106
I want to write hello world example to understand SSO/oauth2
I took following example:
http://www.baeldung.com/sso-spring-security-oauth2
First of all I need to say that it works properply. My question is wy it is working.
My question related with client application. It is simple application which contains only several classes. The most important class is:
UiSecurityConfig:
@Configuration
@EnableOAuth2Sso
public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.authenticated();
}
}
UiWebConfig:
@Configuration
@EnableWebMvc
public class UiWebConfig extends WebMvcConfigurerAdapter {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Override
public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/")
.setViewName("forward:/index");
registry.addViewController("/index");
registry.addViewController("/securedPage");
}
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
and following configuration:
server:
port: 8082
context-path: /ui
session:
cookie:
name: UISESSION
security:
basic:
enabled: false
oauth2:
client:
clientId: SampleClientId
clientSecret: secret
accessTokenUri: http://localhost:8081/auth/oauth/token
userAuthorizationUri: http://localhost:8081/auth/oauth/authorize
resource:
userInfoUri: http://localhost:8081/auth/user/me
spring:
thymeleaf:
cache: false
Questions:
1.When I start application and follows the link http://localhost:8082/ui/ I see login page.
this page contains follwong href
:
<a class="btn btn-primary" href="securedPage">Login</a>
When I click on this href
some sort of magic happens and in the network tab I see:
As you can see
1. http://localhost:8082/ui/securedPage
redirects to http://localhost:8082/ui/login
2. http://localhost:8082/ui/login
redirects to http://localhost:8081/auth/oauth/authorize?client_id=SampleClientId&redirect_uri=http://localhost:8082/ui/login&response_type=code&state=DuO4CX
(!!!another domain!!!how?)
3. http://localhost:8081/auth/oauth/authorize?client_id=SampleClientId&redirect_uri=http://localhost:8082/ui/login&response_type=code&state=DuO4CX
redirects to http://localhost:8081/auth/login
and I see login form where I can input credentials
I don't understand why this works at this way.
1. Why http://localhost:8082/ui/securedPage
redirects to http://localhost:8082/ui/login
???
I don't have mapping for this url. When I start application I see follwing mapping log:
2018-04-12 19:50:04.069 INFO 4388 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Root mapping to handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
2018-04-12 19:50:04.069 INFO 4388 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/index] onto handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
2018-04-12 19:50:04.069 INFO 4388 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/securedPage] onto handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
2018-04-12 19:50:04.085 INFO 4388 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/resources/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-04-12 19:50:04.088 INFO 4388 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
all subesequent steps is unclear too. Please explain it in details.
Upvotes: 1
Views: 1402
Reputation: 1167
http://localhost:8082/ui/login
is not shown in a list of mapped URLs because it is handled by OAuth2ClientAuthenticationProcessingFilter
which initiates the authentication flow.
I think the best way to explain all the steps is to use OAuth 2.0 specification.
Here is the flow scheme:
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
Resource Owner - It's a user
User-Agent - User's browser
Client - Web application deployed on 8082 port
Authorization Server - Web application deployed on 8081 port
(A) The client initiates the flow by directing the resource owner's user-agent to the authorization endpoint. The client includes its client identifier, requested scope, local state, and a redirection URI to which the authorization server will send the user-agent back once access is granted (or denied).
In your case when a user tries to access securedPage
, she is redirected to http://localhost:8082/ui/login
which starts the authentication flow.
After that the user is redirected to the authorization endpoint. In your case it's http://localhost:8081/auth/oauth/authorize
.
(B) The authorization server authenticates the resource owner (via the user-agent) and establishes whether the resource owner grants or denies the client's access request.
Here the user is redirected to the authorization server login page (http://localhost:8081/auth/login
).
(C) Assuming the resource owner grants access, the authorization server redirects the user-agent back to the client using the redirection URI provided earlier (in the request or during client registration). The redirection URI includes an authorization code and any local state provided by the client earlier.
If the authentication was successful, the user is redirected back to the client using the url provided on step (A) in the request to the authorization endpoint. In your case it was &redirect_uri=http://localhost:8082/ui/login
. Redirection includes the authorization code generated by the authorization server.
(D) The client requests an access token from the authorization server's token endpoint by including the authorization code received in the previous step. When making the request, the client authenticates with the authorization server. The client includes the redirection URI used to obtain the authorization code for verification.
(E) The authorization server authenticates the client, validates the authorization code, and ensures that the redirection URI received matches the URI used to redirect the client in step (C). If valid, the authorization server responds back with an access token and, optionally, a refresh token.
The client uses the authorization code to get an access token from the token endpoint (http://localhost:8081/auth/oauth/token
). The access token is used to access protected resources. In your case it's http://localhost:8081/auth/user/me
which is used to fetch information about the user. This information is used to populate the security context.
Upvotes: 3