In meinem alten Projekt, das ich diese Konfiguration verwendet:
@Configuration
@EnableWebSecurity
@Import(WebMvcConfig.class)
@PropertySource(value = { "classpath:config.properties" }, encoding = "UTF-8", ignoreResourceNotFound = false)
public class WebSecWebSecurityCfg extends WebSecurityConfigurerAdapter
{
private UserDetailsService userDetailsService;
@Autowired
@Qualifier("objectMapper")
private ObjectMapper mapper;
@Autowired
@Qualifier("passwordEncoder")
private PasswordEncoder passwordEncoder;
@Autowired
private Environment env;
public WebSecWebSecurityCfg(UserDetailsService userDetailsService)
{
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
JWTAuthorizationFilter authFilter = new JWTAuthorizationFilter
( authenticationManager(),//Auth mgr
env.getProperty("config.secret.symmetric.key"), //Chiave simmetrica
env.getProperty("config.jwt.header.string"), //nome header
env.getProperty("config.jwt.token.prefix") //Prefisso token
);
JWTAuthenticationFilter authenticationFilter = new JWTAuthenticationFilter
(
authenticationManager(), //Authentication Manager
env.getProperty("config.secret.symmetric.key"), //Chiave simmetrica
Long.valueOf(env.getProperty("config.jwt.token.duration")),//Durata del token in millisecondi
env.getProperty("config.jwt.header.string"), //nome header
env.getProperty("config.jwt.token.prefix"), //Prefisso token
mapper
);
http
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.addFilter(authenticationFilter)
.addFilter(authFilter)
// Disabilitiamo la creazione di sessione in spring
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
@Bean
CorsConfigurationSource corsConfigurationSource()
{
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
wo JWTAuthorizationFilter
ist:
public class JWTAuthorizationFilter extends BasicAuthenticationFilter
{
private static final Logger logger = LoggerFactory.getLogger(JWTAuthenticationFilter.class.getName());
private String secretKey;
private String headerString;
private String tokenPrefix;
public JWTAuthorizationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint, String secretKey, String headerString, String tokenPrefix)
{
super(authenticationManager, authenticationEntryPoint);
this.secretKey = secretKey;
this.headerString = headerString;
this.tokenPrefix = tokenPrefix;
}
public JWTAuthorizationFilter(AuthenticationManager authenticationManager, String secretKey, String headerString, String tokenPrefix)
{
super(authenticationManager);
this.secretKey = secretKey;
this.headerString = headerString;
this.tokenPrefix = tokenPrefix;
}
@Override
protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException
{
AuthenticationErrorEnum customErrorCode = null;
StringBuilder builder = new StringBuilder();
if(failed.getCause() instanceof MissingJwtTokenException)
{
customErrorCode = AuthenticationErrorEnum.TOKEN_JWT_MANCANTE;
}
else if(failed.getCause() instanceof ExpiredJwtException)
{
customErrorCode = AuthenticationErrorEnum.TOKEN_JWT_SCADUTO;
}
else if(failed.getCause() instanceof MalformedJwtException)
{
customErrorCode = AuthenticationErrorEnum.TOKEN_JWT_NON_CORRETTO;
}
else if(failed.getCause() instanceof MissingUserSubjectException)
{
customErrorCode = AuthenticationErrorEnum.TOKEN_JWT_NESSUN_UTENTE_TROVATO;
}
else if((failed.getCause() instanceof GenericJwtAuthorizationException) || (failed.getCause() instanceof Exception))
{
customErrorCode = AuthenticationErrorEnum.ERRORE_GENERICO;
}
builder.append("Errore duranre l'autorizzazione. ");
builder.append(failed.getMessage());
JwtAuthApiError apiError = new JwtAuthApiError(HttpStatus.UNAUTHORIZED, failed.getMessage(), Arrays.asList(builder.toString()), customErrorCode);
String errore = (new ObjectMapper()).writeValueAsString(apiError);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.sendError(HttpStatus.UNAUTHORIZED.value(), errore);
request.setAttribute(IRsConstants.API_ERROR_REQUEST_ATTR_NAME, apiError);
}
Und JWTAuthenticationFilter
ist
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter
{
private AuthenticationManager authenticationManager;
private String secretKey;
private long tokenDurationMillis;
private String headerString;
private String tokenPrefix;
private ObjectMapper mapper;
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException
{
AuthenticationErrorEnum customErrorCode = null;
StringBuilder builder = new StringBuilder();
if(failed instanceof BadCredentialsException)
{
customErrorCode = AuthenticationErrorEnum.CREDENZIALI_SERVIZIO_ERRATE;
}
else
{
//Teoricamente nella fase di autenticazione all'errore generico non dovrebbe mai arrivare
customErrorCode = AuthenticationErrorEnum.ERRORE_GENERICO;
}
builder.append("Errore durante l'autenticazione del servizio. ");
builder.append(failed.getMessage());
JwtAuthApiError apiError = new JwtAuthApiError(HttpStatus.UNAUTHORIZED, failed.getMessage(), Arrays.asList(builder.toString()), customErrorCode);
String errore = mapper.writeValueAsString(apiError);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.sendError(HttpStatus.UNAUTHORIZED.value(), errore);
request.setAttribute(IRsConstants.API_ERROR_REQUEST_ATTR_NAME, apiError);
}
public JWTAuthenticationFilter(AuthenticationManager authenticationManager, String secretKey, long tokenDurationMillis, String headerString, String tokenPrefix, ObjectMapper mapper)
{
super();
this.authenticationManager = authenticationManager;
this.secretKey = secretKey;
this.tokenDurationMillis = tokenDurationMillis;
this.headerString = headerString;
this.tokenPrefix = tokenPrefix;
this.mapper = mapper;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException
{
try
{
ServiceLoginDto creds = new ObjectMapper().readValue(req.getInputStream(), ServiceLoginDto.class);
return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(creds.getCodiceServizio(), creds.getPasswordServizio(), new ArrayList<>()));
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication auth) throws IOException, ServletException
{
DateTime dt = new DateTime();
Date expirationTime = dt.plus(getTokenDurationMillis()).toDate();
String token = Jwts
.builder()
.setSubject(((User) auth.getPrincipal()).getUsername())
.setExpiration(expirationTime)
.signWith(SignatureAlgorithm.HS512, getSecretKey().getBytes())
.compact();
res.addHeader(getHeaderString(), getTokenPrefix() + token);
res.addHeader("jwtExpirationDate", expirationTime.toString());
res.addHeader("jwtTokenDuration", String.valueOf(TimeUnit.MILLISECONDS.toMinutes(getTokenDurationMillis()))+" minuti");
}
public String getSecretKey()
{
return secretKey;
}
public void setSecretKey(String secretKey)
{
this.secretKey = secretKey;
}
public long getTokenDurationMillis()
{
return tokenDurationMillis;
}
public void setTokenDurationMillis(long tokenDurationMillis)
{
this.tokenDurationMillis = tokenDurationMillis;
}
public String getHeaderString()
{
return headerString;
}
public void setHeaderString(String headerString)
{
this.headerString = headerString;
}
public String getTokenPrefix()
{
return tokenPrefix;
}
public void setTokenPrefix(String tokenPrefix)
{
this.tokenPrefix = tokenPrefix;
}
}
Der Benutzer Detail ist ein klassische userservicedetail
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
@Autowired
private IServizioService service;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
Service svc;
try
{
svc = service.findBySvcCode(username);
}
catch (DbException e)
{
throw new UsernameNotFoundException("Errore durante il processo di autenticazione; "+e.getMessage(), e);
}
if (svc == null)
{
throw new UsernameNotFoundException("Nessun servizio trovato per il codice servizio "+username);
}
else if(!svc.getAbilitato().booleanValue())
{
throw new UsernameNotFoundException("Servizio "+username+" non abilitato");
}
return new User(svc.getCodiceServizio(), svc.getPasswordServizio(), Collections.emptyList());
}
}
Bitte beachten Sie, ich nicht Frühling
webflux
hätte verwende ich hoffe, es ist nützlich
Angelo
Dank! Aber webflux security funktioniert ganz anders. Aber ich bin mir sicher, dass ich einige Teile verwenden kann. –