213 shaares
2 résultats
taggé
securité
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
/**
* The authentication entry point is called when the client makes a call to a resource without proper authentication. In
* other words, the client has not logged in.
* <p>
* If this class is not present in the code, then Spring security opens a default pop-up. We want a 401 error.
*/
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomAuthenticationEntryPoint.class);
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
LOGGER.info("intercepted request : 401 error code.");
response.getWriter().append("Access Denied : " + authException.getMessage());
response.setStatus(401);
}
}
Cette classe est incluse dans la couche sécurité via la configuration du http :
//Override the default login pop-up with a 401 response.
http.exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint);
Ne reste plus qu'à configurer la gestion des erreurs 401 avec Angular :
import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers } from '@angular/http';
import { Router, NavigationEnd, Event } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
/**
* This class handles generically the error on authentication.
*/
@Injectable()
export class AuthenticatedHttpService extends Http {
private router: Router;
constructor(backend: XHRBackend, defaultOptions: RequestOptions, router: Router) {
super(backend, defaultOptions);
this.router = router;
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return super.request(url, options).catch((error: Response) => {
if ((error.status === 401 || error.status === 403) && (window.location.href.match(/\?/g) || []).length < 2) {
if(window.location.href != '/login') {
this.router.navigate(['/login']);
}
else {
return Observable.throw("authentication met an exception");
}
}
return Observable.throw("request authentication");
});
}
}
Dépendances nécessaire dans Maven :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<scope>compile</scope>
</dependency>
<!-- Pas sure que celle-ci soit nécessaire : -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<scope>compile</scope>
</dependency>
Configuration de la sécurité côté sécurité :
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
@Configuration
@EnableWebSecurity
@ComponentScan("com.pacakge.security")
public class MyWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(MyWebSecurityConfigurerAdapter.class);
@Autowired
@Qualifier("authenticationProvider")
private AuthenticationProvider authenticationProvider;
@Autowired
@Qualifier("isSecurityDisabled")
private Boolean isSecurityDisabled;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationProvider) throws Exception {
authenticationProvider.authenticationProvider(this.authenticationProvider);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
LOGGER.debug("configure HttpSecurity");
LOGGER.info("Security is disabled : {}", isSecurityDisabled);
if (isSecurityDisabled) {
http.httpBasic().and()
.authorizeRequests().antMatchers("/index.html", "/", "/logout.html").permitAll().and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/user").permitAll()
.anyRequest().authenticated();
}
else {
http.httpBasic().and()
.authorizeRequests().antMatchers("/index.html", "/", "/logout.html").permitAll().and()
// configure the csrfTokenRepository
.csrf().csrfTokenRepository(csrfTokenRepository()).and()
.authorizeRequests()
.antMatchers("/user").permitAll()
.antMatchers("/contact/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated();
// Add the csrf filter
http.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
}
http.exceptionHandling().accessDeniedPage("/403");
}
/**
* Csrf Token Repository that contains the header named "X-XSRF-TOKEN".
* Angular adds CRSF token headers to keep sure server and client are not talking to someone else.
*
* @return CsrfTokenRepository
*/
private static CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
@Override
public void configure(WebSecurity web) throws Exception {
LOGGER.info("Security is disabled : {}", isSecurityDisabled);
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
// Spring Security should completely ignore URLs starting with
// /static/assets/
web.ignoring().antMatchers("/static/assets/**").and();
web.ignoring().antMatchers("/static/app/**").and();
// Spring Security should completely ignore URLs for the js / images /
// font
web.ignoring().antMatchers("/static/*.ico").and();
web.ignoring().antMatchers("/static/*.eot").and();
web.ignoring().antMatchers("/static/*.svg").and();
web.ignoring().antMatchers("/static/*.ttf").and();
web.ignoring().antMatchers("/static/*.woff").and();
web.ignoring().antMatchers("/static/*.woff2").and();
web.ignoring().antMatchers("/static/*.js").and();
web.ignoring().antMatchers("/static/*.css").and();
web.ignoring().antMatchers("/static/*.map").and();
web.ignoring().antMatchers("/static/*.png").and();
web.ignoring().antMatchers("/static/*.jpg").and();
}
}
Exemple d'Authentication provider :
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
/**
* A mock for authentication provider.
*/
@Component
public class MockAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
private static final Logger CLASS_LOGGER = LoggerFactory.getLogger(MockAuthenticationProvider.class);
//Your own service to manage authentication.
private final AuthentiService authentiService;
private final LDAPUserToSecurityUserConverter lDAPUserToSecurityUserConverter;
/**
* Initialize the Mock authentication provider.
*
* @param authentiService the authent service.
* @param lDAPUserToSecurityUserConverter the converter from LDAP user to security user.
*/
public MockAuthenticationProvider(LDAPUserToSecurityUserConverter lDAPUserToSecurityUserConverter, AuthentiService authentiService) {
CLASS_LOGGER.trace("Set up of mocked authentication provider.");
this.lDAPUserToSecurityUserConverter = lDAPUserToSecurityUserConverter;
this.authentiService = authentiService;
}
@Override
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
@Override
public Authentication authenticate(Authentication authentication) {
CLASS_LOGGER.info("requesting authentication");
String name = authentication.getName();
String password = authentication.getCredentials().toString();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
SecurityUser authenticatedUser = (SecurityUser) this.retrieveUser(name, (UsernamePasswordAuthenticationToken) authentication);
stopWatch.stop();
authenticatedUser.setTimeToSpentOnAuthentication(stopWatch.getTotalTimeMillis());
return new UsernamePasswordAuthenticationToken(authenticatedUser, password, authenticatedUser.getAuthorities());
}
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) {
String password = (String) authentication.getCredentials();
try {
// Login User
String token = this.authentService.login(username, password);
CLASS_LOGGER.debug("Username : {} got token : {}", username, token);
// Retrieve User Identity + roles + permissions
LDAPUser user = this.authentService.getUserInformation(token);
// Build the AuthenticatedUser object based on all the data
return this.lDAPUserToSecurityUserConverter.convert(user, password, token);
}
catch (Exception e) {
CLASS_LOGGER.debug(e.getMessage(), e);
throw new AuthenticationServiceException("Authentication error", e);
}
}
@Override
protected void additionalAuthenticationChecks(UserDetails arg0, UsernamePasswordAuthenticationToken arg1) throws AuthenticationException {
// Nothing to do.
}
}
Controller d'authentication :
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AuthenticationController {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationController.class);
@RequestMapping(value = "/user", method = RequestMethod.GET)
public SecurityUser user() {
LOGGER.debug("user controller");
SecurityUser authenticationUser = null;
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
LOGGER.info("Authentication provider is {}", auth.getClass().getSimpleName());
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) auth;
authenticationUser = (SecurityUser) usernamePasswordAuthenticationToken.getPrincipal();
}
else {
LOGGER.warn("No Authentication found");
}
return authenticationUser;
}
}
Service Angular d'authentication :
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions, URLSearchParams } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Observable } from 'rxjs/Observable';
/**
* This class can request the server to get contact information.
*/
@Injectable()
export class AuthenticationService {
constructor(private http: Http) {
}
authenticate(username: string, password: string): Observable<any> {
//Authentication goes by using headers
const headers = new Headers();
if (username != null && password != null) {
const authorizationValue: string = 'Basic ' + btoa(username + ':' + password);
headers.append('authorization', authorizationValue);
}
return this.http.get('user', {headers: headers})
.map((res: Response) => res.json())
.catch( error => this.handleError(error) );
}
}