Commit 32071373 authored by Andrey Lugovskiy's avatar Andrey Lugovskiy
Browse files

- added jwt

parent c75a9437
......@@ -18,7 +18,6 @@ package org.genesys.catalog.service.impl;
import java.util.HashSet;
import java.util.UUID;
import org.genesys.blocks.security.service.CustomAclService;
import org.genesys.catalog.service.PartnerService;
import org.genesys.catalog.service.filters.PartnerFilter;
import org.genesys.common.model.Partner;
......@@ -30,7 +29,6 @@ import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -47,9 +45,6 @@ public class PartnerServiceImpl implements PartnerService {
@Autowired
private PartnerRepository partnerRepository;
@Autowired
private CustomAclService aclService;
/**
* {@inheritDoc}
*/
......
......@@ -45,7 +45,7 @@
<google.api.version>1.22.0</google.api.version>
<querydsl.version>4.1.4</querydsl.version>
<spring.security.version>4.1.3.RELEASE</spring.security.version>
<oauth2.version>2.0.13.RELEASE</oauth2.version>
<oauth2.version>2.2.0.RELEASE</oauth2.version>
<hibernate.version>4.3.11.Final</hibernate.version>
<hsqldb.version>2.3.4</hsqldb.version>
<ehcache.version>2.7.4</ehcache.version>
......
......@@ -18,6 +18,7 @@
<swagger.version>2.7.0</swagger.version>
<tomcat-jdbc-juli>8.5.13</tomcat-jdbc-juli>
<liquibase.version>3.5.3</liquibase.version>
<spring-security-jwt>1.0.8.RELEASE</spring-security-jwt>
</properties>
<build>
......@@ -334,6 +335,13 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>${spring-security-jwt}</version>
</dependency>
<!--LOG -->
<dependency>
<groupId>org.slf4j</groupId>
......
package org.genesys.catalog.server.config;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.stereotype.Component;
/**
* Class for add custom value in token json.
*
* @author Andrey Lugovskoy.
*/
@Component
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
// Map<String, Object> additionalInfo = new HashMap<>();
// additionalInfo.put("organization", authentication.getName() + randomAlphabetic(4));
// ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
}
}
......@@ -18,6 +18,7 @@ package org.genesys.catalog.server.config;
import org.genesys.blocks.oauth.service.OAuthServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
......@@ -38,113 +39,138 @@ import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import java.util.Arrays;
@Configuration
public class OAuth2ServerConfig {
private static final String APPLICATION_RESOURCE_ID = "genesyscatalog";
@Bean
public OAuthServiceImpl oauthService() {
return new OAuthServiceImpl();
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(final ResourceServerSecurityConfigurer resources) {
resources.resourceId(APPLICATION_RESOURCE_ID).stateless(false);
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
// Since we want the protected resources to be accessible in the UI as well we need
// session creation to be allowed (it's disabled by default in 2.0.6)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// cors
.and()
.cors()
.and()
.requestMatchers()
.antMatchers("/api/**", "/google/verify-token", "/token")
.and()
.authorizeRequests()
.antMatchers("/api/**", "/google/verify-token", "/token").authenticated()
.and()
.exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
@Qualifier("userService")
private UserDetailsService userDetailsService;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
@Qualifier("oauthService")
private ClientDetailsService clientDetailsService;
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.userDetailsService(userDetailsService)
.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
}
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.allowFormAuthenticationForClients()
.checkTokenAccess("permitAll()")
.realm(APPLICATION_RESOURCE_ID + "/client");
}
}
@Configuration
protected static class Stuff {
@Autowired
@Qualifier("oauthService")
private TokenStore tokenStore;
@Bean
public ApprovalStore approvalStore() throws Exception {
final TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore);
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
private static final String APPLICATION_RESOURCE_ID = "genesyscatalog";
@Bean
public OAuthServiceImpl oauthService() {
return new OAuthServiceImpl();
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public ApprovalStore approvalStore() throws Exception {
final TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore());
return store;
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(APPLICATION_RESOURCE_ID);
return converter;
}
@Configuration
@EnableResourceServer
protected class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
// Since we want the protected resources to be accessible in the UI as well we need
// session creation to be allowed (it's disabled by default in 2.0.6)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// cors
.and().cors()
.and().requestMatchers().antMatchers("/api/**", "/google/verify-token", "/token")
.and().authorizeRequests().antMatchers("/api/**", "/google/verify-token", "/token").authenticated()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
@Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices()).resourceId(APPLICATION_RESOURCE_ID).stateless(false);
}
}
@Configuration
@EnableAuthorizationServer
protected class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Value("${access_token.validity_period}")
int accessTokenValiditySeconds = 3600;
@Autowired
@Qualifier("userService")
private UserDetailsService userDetailsService;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
@Qualifier("oauthService")
private ClientDetailsService clientDetailsService;
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(APPLICATION_RESOURCE_ID);
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "client_credentials")
.scopes("read", "write", "trust")
.resourceIds(APPLICATION_RESOURCE_ID)
.secret("my-secret-client")
.accessTokenValiditySeconds(accessTokenValiditySeconds);
}
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients().checkTokenAccess("permitAll()").realm(APPLICATION_RESOURCE_ID + "/client");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain).userDetailsService(userDetailsService).authenticationManager(authenticationManager);
}
}
}
......@@ -25,8 +25,8 @@ import org.springframework.security.config.annotation.method.configuration.Enabl
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
......@@ -47,8 +47,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
// No JSESSIONID in URL
.sessionManagement().enableSessionUrlRewriting(false)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// Authorizations
.and().authorizeRequests()
// Rules
......@@ -60,7 +61,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
// access denied
.accessDeniedPage("/user/login?authorization_error=true")
.and()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable()
// Logout and login
.logout()
.logoutUrl("/logout")
......@@ -78,5 +78,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
......@@ -32,7 +32,6 @@ import java.util.UUID;
/**
* @author Andrey Lugovskoy.
*/
//TODO clarify permissions
@RestController
@RequestMapping(DatasetController.API_BASE)
@PreAuthorize("isAuthenticated()")
......
......@@ -52,36 +52,36 @@ public class DescriptorController {
@Autowired
private DescriptorService descriptorService;
@RequestMapping(value = "/descriptor-list/{UUID}", method = RequestMethod.GET)
@GetMapping(value = "/descriptor-list/{UUID}")
public DescriptorList getDescriptorList(@PathVariable("UUID") final UUID uuid) {
final DescriptorList descriptorList = descriptorListService.findDescriptorListByUUID(uuid);
return descriptorList;
}
@RequestMapping(value = "/descriptor-list/remove", method = RequestMethod.DELETE)
@DeleteMapping(value = "/descriptor-list/remove")
public DescriptorList removeDescriptorList(@RequestBody final DescriptorList source) {
final DescriptorList descriptorList = descriptorListService.deleteDescriptorList(source.getUuid(), source.getVersion());
return descriptorList;
}
@RequestMapping(value = "/descriptor-list/{UUID},{version}", method = RequestMethod.DELETE)
@DeleteMapping(value = "/descriptor-list/{UUID},{version}")
public DescriptorList deleteDescriptorList(@PathVariable("UUID") final UUID uuid, @PathVariable("version") final int version) {
return descriptorListService.deleteDescriptorList(uuid, version);
}
@RequestMapping(value = "/descriptor-list/create", method = RequestMethod.POST)
@PostMapping(value = "/descriptor-list/create")
public DescriptorList createDescriptorList(@RequestBody final DescriptorList source) {
final DescriptorList descriptorList = descriptorListService.createDescriptorList(source);
return descriptorList;
}
@RequestMapping(value = "/descriptor-list/update", method = RequestMethod.POST)
@PostMapping(value = "/descriptor-list/update")
public DescriptorList updateDescriptorList(@RequestBody final DescriptorList source) {
final DescriptorList descriptorList = descriptorListService.updateDescriptorList(source);
return descriptorList;
}
@RequestMapping(value = "/descriptor-list/list", method = RequestMethod.GET)
@GetMapping(value = "/descriptor-list/list")
public Page<DescriptorList> listDescriptorLists(@RequestParam(name = "p", required = false, defaultValue = "0") final int page,
@RequestParam(name = "l", required = false, defaultValue = "50") final int pageSize, @RequestParam(name = "d", required = false, defaultValue = "ASC") final Sort.Direction direction,
@RequestParam(name = "s", required = false, defaultValue = "id") final String[] sort) {
......
......@@ -15,7 +15,6 @@
*/
package org.genesys.catalog.server.controller.api.v0;
import org.genesys.blocks.security.service.CustomAclService;
import org.genesys.catalog.service.PartnerService;
import org.genesys.catalog.service.filters.PartnerFilter;
import org.genesys.common.model.Partner;
......@@ -24,6 +23,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
......@@ -57,7 +57,7 @@ public class PartnerController {
return partnerService.filterPartner(partnerFilter, new PageRequest(page, Integer.min(pageSize, 100), direction, sort));
}
@RequestMapping(value = "/{UUID}", method = RequestMethod.GET)
@GetMapping(value = "/{UUID}")
public Partner getPartner(@PathVariable("UUID") final UUID uuid) {
return partnerService.partnerByUuid(uuid);
}
......
......@@ -44,3 +44,5 @@ s3.prefix=
# Antivirus
CLAMD_HOSTNAME=
CLAMD_PORT=
access_token.validity_period=3600
......@@ -2692,6 +2692,280 @@ databaseChangeLog:
name: role
type: VARCHAR(255)
tableName: datasetcreator
# User and OAuthClient extend AclSid
- changeSet:
id: 1509390480000-1
author: matijaobreza
comment: Migrate ACL to app-blocks-1.3-SNAPSHOT
changes:
- dropForeignKeyConstraint:
baseTableName: acl_entry
constraintName: FK_fhuoesmjef3mrv0gpja4shvcr
- dropForeignKeyConstraint:
baseTableName: acl_entry
constraintName: FK_i6xyfccd4y3wlwhgwpo4a9rm1
- dropForeignKeyConstraint:
baseTableName: acl_object_identity
constraintName: FK_nxv5we2ion9fwedbkge7syoc3
- dropUniqueConstraint:
tableName: acl_entry
constraintName: UK_gh5egfpe4gaqokya6s0567b0l
- renameTable:
oldTableName: acl_sid
newTableName: acl_sid_backup
- renameTable:
oldTableName: acl_entry
newTableName: acl_entry_backup
- createTable:
columns:
- column:
constraints:
nullable: true
name: type
type: INT
- column:
autoIncrement: true
constraints:
primaryKey: true
name: id
type: BIGINT
- column:
constraints:
nullable: false
name: active
type: BIT(1)
defaultValue: true
- column:
constraints:
nullable: false
name: version
type: INT
- column:
name: created_by
type: BIGINT
- column:
name: created_date
type: datetime(6)
- column:
name: last_modified_by
type: BIGINT
- column:
name: last_modified_date
type: datetime(6)
- column:
constraints:
nullable: false
name: principal
type: BIT(1)
- column:
constraints:
nullable: false
name: sid
type: VARCHAR(100)
tableName: acl_sid
- createTable:
columns:
- column:
autoIncrement: true
constraints:
primaryKey: true
name: id
type: BIGINT
- column:
constraints:
nullable: false
name: ace_order
type: BIGINT
- column:
constraints:
nullable: false
name: audit_failure
type: BIT(1)
- column:
constraints:
nullable: false
name: audit_success
type: BIT(1)
- column:
constraints:
nullable: false
name: granting
type: BIT(1)
- column:
constraints:
nullable: false
name: mask
type: BIGINT
- column:
constraints:
nullable: false
name: acl_object_identity
type: BIGINT
- column:
constraints:
nullable: false
name: sid
type: BIGINT
tableName: acl_entry