blob: fbde01860366ff4fa8bcec87cd56998816b9d93e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.core.spring.security;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.KeyLengthException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.spring.security.jws.AccessTokenJWSSigner;
import org.apache.syncope.core.spring.security.jws.AccessTokenJWSVerifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
@EnableConfigurationProperties(SecurityProperties.class)
@Configuration
public class SecurityContext {
private static final Logger LOG = LoggerFactory.getLogger(SecurityContext.class);
@Autowired
private SecurityProperties props;
@Bean
public String adminUser() {
return props.getAdminUser();
}
@Bean
public String adminPassword() {
return props.getAdminPassword();
}
@Bean
public CipherAlgorithm adminPasswordAlgorithm() {
return props.getAdminPasswordAlgorithm();
}
@Bean
public String anonymousUser() {
return props.getAnonymousUser();
}
@Bean
public String anonymousKey() {
return props.getAnonymousKey();
}
@Bean
public String jwtIssuer() {
return props.getJwtIssuer();
}
@Bean
public JWSAlgorithm jwsAlgorithm() {
return JWSAlgorithm.parse(props.getJwsAlgorithm().toUpperCase());
}
@Bean
public String jwsKey() {
String jwsKey = props.getJwsKey();
if (jwsKey == null) {
throw new IllegalArgumentException("No JWS key provided");
}
JWSAlgorithm jwsAlgorithm = jwsAlgorithm();
if (JWSAlgorithm.Family.HMAC_SHA.contains(jwsAlgorithm)) {
int minLength = jwsAlgorithm.equals(JWSAlgorithm.HS256)
? 256 / 8
: jwsAlgorithm.equals(JWSAlgorithm.HS384)
? 384 / 8
: 512 / 8;
if (jwsKey.length() < minLength) {
jwsKey = SecureRandomUtils.generateRandomPassword(minLength);
props.setJwsKey(jwsKey);
LOG.warn("The configured key for {} must be at least {} bits, generating random: {}",
jwsAlgorithm, minLength * 8, jwsKey);
}
}
return jwsKey;
}
@ConditionalOnMissingBean
@Bean
public DefaultCredentialChecker credentialChecker() {
return new DefaultCredentialChecker(jwsKey(), adminPassword(), anonymousKey());
}
@ConditionalOnMissingBean
@Bean
public AccessTokenJWSVerifier accessTokenJWSVerifier()
throws JOSEException, NoSuchAlgorithmException, InvalidKeySpecException {
return new AccessTokenJWSVerifier(jwsAlgorithm(), jwsKey());
}
@ConditionalOnMissingBean
@Bean
public AccessTokenJWSSigner accessTokenJWSSigner()
throws KeyLengthException, NoSuchAlgorithmException, InvalidKeySpecException {
return new AccessTokenJWSSigner(jwsAlgorithm(), jwsKey());
}
@ConditionalOnMissingBean
@Bean
public PasswordGenerator passwordGenerator() {
return new DefaultPasswordGenerator();
}
@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
}
@Bean
public ApplicationContextProvider applicationContextProvider() {
return new ApplicationContextProvider();
}
}