This is the codeAbility Sharing Platform! Learn more about the codeAbility Sharing Platform.

Skip to content
Snippets Groups Projects
Commit 0cc69dcc authored by Michael Breu's avatar Michael Breu :speech_balloon:
Browse files

First running version!

parent 2ddafe5f
2 merge requests!17Initial Merge to Prepare Release 1.0.0,!1Resolve "Metadaten konsolideren"
......@@ -30,14 +30,19 @@
"clientTheme": "none",
"clientThemeVariant": "",
"creationTimestamp": 1593593458485,
"testFrameworks": ["protractor"],
"testFrameworks": [
"protractor"
],
"jhiPrefix": "jhi",
"entitySuffix": "",
"dtoSuffix": "DTO",
"otherModules": [],
"enableTranslation": true,
"nativeLanguage": "en",
"languages": ["en", "de"],
"languages": [
"en",
"de"
],
"blueprints": []
}
}
......@@ -2,10 +2,16 @@ package at.ac.uibk.gitsearch.config;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
import java.io.IOException;
import java.net.URI;
import java.security.Principal;
import java.util.Collection;
import java.util.Collections;
import javax.servlet.DispatcherType;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
......@@ -19,15 +25,19 @@ import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
......@@ -38,6 +48,9 @@ import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.endpoint.PkceParameterNames;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders;
......@@ -45,6 +58,8 @@ import org.springframework.security.oauth2.jwt.JwtValidators;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
......@@ -128,12 +143,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.deny()
.and()
.sessionManagement()
// We need a stateful session management here!
// .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/oauth2/**").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/refreshToken").permitAll()
.antMatchers("/api/register").denyAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
......@@ -148,7 +163,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.and()
.apply(securityConfigurerAdapter())
.and()
.oauth2Login()
.oauth2Login().successHandler(getAuthenticationSuccessHandler())
.and()
.oauth2ResourceServer() // .bearerTokenResolver(bearerTokenResolver)
.jwt()
......@@ -321,6 +336,120 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
}
}
public AuthenticationSuccessHandler getAuthenticationSuccessHandler() {
SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport successHandler = new SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport(tokenProvider);
return successHandler;
}
/**
* allows for a redirect with a fragment that encodes a short lived JWT-Token
* @author Michael Breu
*
*/
public static class SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport extends SavedRequestAwareAuthenticationSuccessHandler {
protected TokenProvider tokenProvider;
public SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport(TokenProvider tokenProvider) {
super();
this.tokenProvider = tokenProvider;
}
@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
String plainTargetUrl = super.determineTargetUrl(request, response, authentication);
Authentication authenticationForToken = authentication;
if (authentication instanceof OAuth2AuthenticationToken) {
OAuth2AuthenticationToken oAuthA = (OAuth2AuthenticationToken) authentication;
String mail = ((OidcUser) ((OAuth2AuthenticationToken) authentication).getPrincipal()).getEmail();
String idToken = oAuthA.getPrincipal().getAttribute("idToken");
authenticationForToken = new SimpleAuthentication(new SimplePrincipal(mail), authentication.getAuthorities());
authenticationForToken.setAuthenticated(authentication.isAuthenticated());
}
String token = tokenProvider.createToken(authenticationForToken, 200000L); // 200 secs (for Debugging)
return plainTargetUrl + "#requestToken=" + token;
}
}
public static class SimplePrincipal implements Principal {
protected String name;
public SimplePrincipal(String name) {
super();
this.name = name;
}
@Override
public String getName() {
return name;
}
}
public static class SimpleAuthentication implements Authentication {
/**
*
*/
private static final long serialVersionUID = -791646857551363545L;
private Principal principal;
Collection<? extends GrantedAuthority> authorities;
public SimpleAuthentication(Principal principal, Collection<? extends GrantedAuthority> authorities) {
super();
this.principal = principal;
this.authorities = authorities;
}
@Override
public String getName() {
return principal.getName();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return principal;
}
private boolean authenticated = false;
@Override
public boolean isAuthenticated() {
return authenticated;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
authenticated = isAuthenticated;
}
}
}
......@@ -60,26 +60,41 @@ public class TokenProvider {
.getTokenValidityInSecondsForRememberMe();
}
/**
* creates a token for authentication with validity determined by rememberMe.
* @param authentication
* @param rememberMe
* @return
*/
public String createToken(Authentication authentication, boolean rememberMe) {
String authorities = authentication.getAuthorities().stream()
long validity = rememberMe
?tokenValidityInMillisecondsForRememberMe
:tokenValidityInMilliseconds;
return createToken(authentication, validity);
}
/**
* creates a token from authentication given by validity (im msec)
* @param authentication the authentication
* @param validity validity in msec
* @return
*/
public String createToken(Authentication authentication, long validity) {
Date endTime = new Date(System.currentTimeMillis() + validity);
String authorities = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));
long now = (new Date()).getTime();
Date validity;
if (rememberMe) {
validity = new Date(now + this.tokenValidityInMillisecondsForRememberMe);
} else {
validity = new Date(now + this.tokenValidityInMilliseconds);
}
return Jwts.builder()
.setSubject(authentication.getName())
.claim(AUTHORITIES_KEY, authorities)
.signWith(key, SignatureAlgorithm.HS512)
.setExpiration(validity)
.setExpiration(endTime)
.compact();
}
}
public Authentication getAuthentication(String token) {
Claims claims = Jwts.parserBuilder()
......
......@@ -47,6 +47,21 @@ public class UserJWTController {
httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt);
return new ResponseEntity<>(new JWTToken(jwt), httpHeaders, HttpStatus.OK);
}
@PostMapping("/refreshToken")
public ResponseEntity<JWTToken> authorize(@RequestParam("token") String token) {
if(!tokenProvider.validateToken(token)) {
return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED);
} else {
Authentication authentication = tokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.createToken(authentication, false);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt);
return new ResponseEntity<>(new JWTToken(jwt), httpHeaders, HttpStatus.OK);
}
}
/**
* Object to return as body in JWT Authentication.
*/
......
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { LocalStorageService, SessionStorageService } from 'ngx-webstorage';
......@@ -25,6 +25,13 @@ export class AuthServerProvider {
.pipe(map(response => this.authenticateSuccess(response, credentials.rememberMe)));
}
refreshToken(tokenX: string): Observable<void> {
const tokenParam = new HttpParams().set('token', tokenX);
return this.http
.post<JwtToken>(SERVER_API_URL + 'api/refreshToken', tokenParam )
.pipe(map(response => this.authenticateSuccess(response, false)));
}
logout(): Observable<void> {
return new Observable(observer => {
this.$localStorage.clear('authenticationToken');
......
......@@ -4,6 +4,7 @@ import { Router, ActivatedRouteSnapshot, NavigationEnd, NavigationError } from '
import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
import { AccountService } from 'app/core/auth/account.service';
import { AuthServerProvider } from 'app/core/auth/auth-jwt.service';
@Component({
selector: 'jhi-main',
......@@ -17,7 +18,8 @@ export class MainComponent implements OnInit {
private titleService: Title,
private router: Router,
private translateService: TranslateService,
rootRenderer: RendererFactory2
rootRenderer: RendererFactory2,
private authServerProvider: AuthServerProvider
) {
this.renderer = rootRenderer.createRenderer(document.querySelector('html'), null);
}
......@@ -40,8 +42,39 @@ export class MainComponent implements OnInit {
this.renderer.setAttribute(document.querySelector('html'), 'lang', langChangeEvent.lang);
});
this.routeEvent(this.router);
}
private routeEvent(router: Router):void {
router.events.subscribe(e => {
if(e instanceof NavigationEnd){
this.checkRequestToken();
}
});
}
private checkRequestToken(): void {
const fr = this.router.parseUrl(this.router.url).fragment;
if(fr) {
const regexp = /requestToken=(\w+)/;
if(regexp.test(fr)) {
const token = fr.replace(regexp, "$1");
if(token && token.length> 20)
this.authServerProvider.refreshToken(token)
.subscribe(
() => {
this.accountService.identity(true).subscribe();
this.router.navigate(['']);
},
() => {
const xxx = "abc";
}
); }
}
}
private getPageTitle(routeSnapshot: ActivatedRouteSnapshot): string {
let title: string = routeSnapshot.data && routeSnapshot.data['pageTitle'] ? routeSnapshot.data['pageTitle'] : '';
if (routeSnapshot.firstChild) {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment