All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.vaadin.spring.security.Security Maven / Gradle / Ivy

There is a newer version: 0.0.5.RELEASE
Show newest version
/*
 * 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