org.vaadin.spring.security.Security Maven / Gradle / Ivy
/*
* Copyright 2014 The original authors
*
* Licensed 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.vaadin.spring.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.Assert;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
/**
* Convenience class that provides the Spring Security operations that are most commonly required in a Vaadin application.
*
* @author Petter Holmström ([email protected])
*/
public class Security {
private final AuthenticationManager authenticationManager;
private final AccessDecisionManager accessDecisionManager;
private final ApplicationContext applicationContext;
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired(required = false)
public Security(AuthenticationManager authenticationManager, AccessDecisionManager accessDecisionManager, ApplicationContext applicationContext) {
this.authenticationManager = authenticationManager;
if (authenticationManager == null) {
logger.warn("No AuthenticationManager set! Some security methods will not be available.");
}
this.accessDecisionManager = accessDecisionManager;
if (accessDecisionManager == null) {
logger.warn("No AccessDecisionManager set! Some security methods will not be available.");
}
Assert.notNull(applicationContext);
this.applicationContext = applicationContext;
}
private AuthenticationManager getAuthenticationManager() {
if (authenticationManager == null) {
throw new IllegalStateException("No AuthenticationManager has been set");
}
return authenticationManager;
}
/**
* Checks if the current user is authenticated.
*
* @return true if the current {@link org.springframework.security.core.context.SecurityContext} contains an {@link org.springframework.security.core.Authentication} token,
* and the token has been authenticated by an {@link org.springframework.security.authentication.AuthenticationManager}.
* @see org.springframework.security.core.Authentication#isAuthenticated()
*/
public boolean isAuthenticated() {
final Authentication authentication = getAuthentication();
return authentication != null && authentication.isAuthenticated();
}
/**
* Tries to login using the specified authentication object. If authentication succeeds, this method
* will return without exceptions.
*
* @param authentication the authentication object to authenticate, must not be {@code null}.
* @throws org.springframework.security.core.AuthenticationException if authentication fails.
*/
public void login(Authentication authentication) throws AuthenticationException {
final Authentication fullyAuthenticated = getAuthenticationManager().authenticate(authentication);
final SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(fullyAuthenticated);
}
/**
* Convenience method that invokes {@link #login(org.springframework.security.core.Authentication)} with a
* {@link org.springframework.security.authentication.UsernamePasswordAuthenticationToken}-object.
*
* @param username the username to use, must not be {@code null}.
* @param password the password to use, must not be {@code null}.
* @throws AuthenticationException if authentication fails.
*/
public void login(String username, String password) throws AuthenticationException {
login(new UsernamePasswordAuthenticationToken(username, password));
}
/**
* Logs the user out, clearing the {@link org.springframework.security.core.context.SecurityContext} without
* invalidating the session.
*/
public void logout() {
final SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(null);
}
/**
* Checks if the current user has the specified authority. This method works with static authorities (such as roles).
* If you need more dynamic authorization (such as ACLs or EL expressions), use {@link #hasAccessToObject(Object, String...)}.
*
* @param authority the authority to check, must not be {@code null}.
* @return true if the current {@link org.springframework.security.core.context.SecurityContext} contains an authenticated {@link org.springframework.security.core.Authentication}
* token that has a {@link org.springframework.security.core.GrantedAuthority} whose string representation matches the specified {@code authority}.
* @see org.springframework.security.core.Authentication#getAuthorities()
* @see org.springframework.security.core.GrantedAuthority#getAuthority()
*/
public boolean hasAuthority(String authority) {
final Authentication authentication = getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return false;
}
for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
if (authority.equals(grantedAuthority.getAuthority())) {
return true;
}
}
return false;
}
/**
* Gets the authentication token of the current user.
*
* @return the {@link org.springframework.security.core.Authentication} token stored in the current {@link org.springframework.security.core.context.SecurityContext}, or {@code null}.
*/
public Authentication getAuthentication() {
final SecurityContext securityContext = SecurityContextHolder.getContext();
final Authentication authentication = securityContext.getAuthentication();
return authentication;
}
/**
* Checks if the current user is authorized based on the specified security configuration attributes. The attributes
* can be roles or Spring EL expressions (basically anything you can specify as values of the {@link org.springframework.security.access.annotation.Secured} annotation).
*
* @param securedObject the secured object.
* @param securityConfigurationAttributes the security configuration attributes.
* @return true if the current user is authorized, false if not.
*/
public boolean hasAccessToObject(Object securedObject, String... securityConfigurationAttributes) {
final Authentication authentication = getAuthentication();
if (accessDecisionManager == null || authentication == null || !authentication.isAuthenticated()) {
if (accessDecisionManager == null) {
logger.warn("Access was denied to object because there was no AccessDecisionManager set!");
}
return false;
}
final Collection configAttributes = new ArrayList(securityConfigurationAttributes.length);
for (String securityConfigString : securityConfigurationAttributes) {
configAttributes.add(new SecurityConfig(securityConfigString));
}
try {
accessDecisionManager.decide(authentication, securedObject, configAttributes);
return true;
} catch (AccessDeniedException ex) {
return false;
} catch (InsufficientAuthenticationException ex) {
return false;
}
}
/**
* Convenience method that invokes {@link #hasAccessToObject(Object, String...)}, using the {@link org.springframework.security.access.annotation.Secured} annotation of the secured object
* to get the security configuration attributes.
*
* @param securedObject the secured object, must not be {@code null} and must have the {@link org.springframework.security.access.annotation.Secured} annotation.
* @return true if the current user is authorized, false if not.
*/
public boolean hasAccessToSecuredObject(Object securedObject) {
final Secured secured = AopUtils.getTargetClass(securedObject).getAnnotation(Secured.class);
Assert.notNull(secured, "securedObject did not have @Secured annotation");
return hasAccessToObject(securedObject, secured.value());
}
/**
* Uses the {@link org.springframework.security.access.annotation.Secured} annotation on the specified method to check if the current user has access to the secured object.
*
* @param securedObject the secured object, must not be {@code null}.
* @param methodName the name of the method holding the {@link org.springframework.security.access.annotation.Secured} annotation.
* @param methodParameterTypes the parameter types of the method holding the {@link org.springframework.security.access.annotation.Secured} annotation.
* @return true if the current user is authorized, false if not.
* @see #hasAccessToSecuredObject(Object)
*/
public boolean hasAccessToSecuredMethod(Object securedObject, String methodName, Class>... methodParameterTypes) {
try {
final Method method = securedObject.getClass().getMethod(methodName, methodParameterTypes);
final Secured secured = AnnotationUtils.findAnnotation(method, Secured.class);
Assert.notNull(secured, "securedObject did not have @Secured annotation");
return hasAccessToObject(securedObject, secured.value());
} catch (NoSuchMethodException ex) {
throw new IllegalArgumentException("Method " + methodName + " does not exist", ex);
}
}
/**
* Checks if the current user has all required authorities.
*
* @param authorities the required authorities.
* @return true if the current user is authenticated and has all of the specified authorities.
* @see #hasAuthority(String)
* @see #hasAnyAuthority(String...)
*/
public boolean hasAuthorities(String... authorities) {
for (String authority : authorities) {
if (!hasAuthority(authority)) {
return false;
}
}
return true;
}
/**
* Checks if the current user has at least one of the specified authorities.
*
* @param authorities the authorities.
* @return true if the current user is authenticated and has at least one of the specified authorities.
* @see #hasAuthority(String)
* @see #hasAuthorities(String...)
*/
public boolean hasAnyAuthority(String... authorities) {
for (String authority : authorities) {
if (hasAuthority(authority)) {
return true;
}
}
return false;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy