简体   繁体   中英

Grails Spring Security

I am trying to create a login page which will log in into the specific account depending on which role does the user have but for some reason the spring security never recogonizes the username and password

Here is the LoginController

package login_page

import grails.plugin.springsecurity.userdetails.DefaultPostAuthenticationChecks import org.springframework.security.access.annotation.Secured

@Secured('permitAll') class LoginController extends grails.plugin.springsecurity.LoginController {

PersonService personService

def index() {
    if (isLoggedIn()) {
        redirect uri: conf.successHandler.defaultTargetUrl
    }
    else {
        redirect action: 'auth', params: params
    }
}
def auth() {

    def conf = getConf()

    if (isLoggedIn()) {
        redirect uri: conf.successHandler.defaultTargetUrl
        return
    }

    String postUrl = request.contextPath + conf.apf.filterProcessesUrl
    render view: 'index', model: [postUrl: postUrl,
                                 rememberMeParameter: conf.rememberMe.parameter,
                                 usernameParameter: conf.apf.usernameParameter,
                                 passwordParameter: conf.apf.passwordParameter,
                                ]
}

}

and success uri is /person/LoginPage

and the LoginPage method is this

   @Secured(['ROLE_USER','ROLE_ADMIN','ROLE_SUPERADMIN'])
def LoginPage() {
      refreshCurrentUser()
    if (currentPerson == null) {
        notFound()
    }else {
        if(currentPerson.getAuthorities()[0].getAuthority()=="ROLE_SUPERADMIN"){
            redirect(controller:'superAdmin', action: 'superAdminShow', id: currentPerson.id)
        }
       else if(currentPerson.getAuthorities()[0].getAuthority()=="ROLE_ADMIN"){
            redirect(controller:'admin', action: 'adminShow', id: currentPerson.id)
        }
        else if(currentPerson.getAuthorities()[0].getAuthority()=="ROLE_USER"){
            redirect(action: 'show', id: currentPerson.id)
        }
    }
}

This is a very simple security configuration that I put together on the fly (a Reactive Java Rest API) for a silly demo. I am by no means a security expert, but it can give you an idea of the things involved.

import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import XXXXXXXX.Permissions;
import XXXXXXXXX.UserPermissions;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity.AuthorizeExchangeSpec;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import reactor.core.publisher.Mono;


@Configuration
@EnableWebFluxSecurity
public class ApiSecurityConfiguration implements ReactiveAuthenticationManager{

    @Autowired
    Permissions permissions;
    @Autowired
    RedisTemplate<String, Object> redisCache;

    private static final Logger logger = LoggerFactory.getLogger(ApiSecurityConfiguration.class);
    private UserPermissions userPermissionTable;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        AuthorizeExchangeSpec authorize;
        http.formLogin().disable();
        http.csrf().disable();
        http.logout().disable();å
        http.httpBasic().disable();
        http.httpBasic().
        authenticationManager(this::authenticate);
        authorize = http.authorizeExchange();
        authorize.anyExchange().access(this::check);

        return http.build();
    }

    private Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext context) {
        return authentication.map(a ->this.checkAuthorizations(a, context)).map(granted -> new AuthorizationDecision(granted));
    }

    private boolean checkAuthorizations(Authentication a, AuthorizationContext context){
        boolean ret = false;
        String name = a.getName();
        if (a.isAuthenticated()){
            logger.info(String.format("FOUND %s, authorizing...", name));
            ret = userPermissionTable.canAccess("XXXX", context.getExchange().getRequest().getPath().value(), context.getExchange().getRequest().getMethodValue());
            logger.info(String.format("%s access granted: %B", name, ret));
        }
        return ret;
    }

    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        CompletableFuture<UserPermissions> cup;
        Authentication auth;
        String name = null;

        auth = authentication;
        auth.setAuthenticated(false);
        try {
            name = authentication.getName();
            logger.info(String.format("Looking %s in cache...", name));
            userPermissionTable = (UserPermissions)redisCache.opsForValue().get(name);
            if (userPermissionTable == null){
                logger.info(String.format("NOT in cache, authenticating: %s ...", name));
                cup = permissions.getPermissionsForUser(name, authentication.getCredentials().toString());
                userPermissionTable = cup.get(1000, TimeUnit.MILLISECONDS);
                redisCache.opsForValue().set(name, userPermissionTable, userPermissionTable.getTTL(), TimeUnit.MINUTES);
                auth = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), null);
                logger.info(String.format("Authenticated: %s", name));
            }
            else{
                auth = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), null);
                redisCache.expire(name, userPermissionTable.getTTL(), TimeUnit.MINUTES);
            }
        } catch (Exception e) {
            logger.info(String.format("FAILED to authenticate: %s", name));
        }
        return Mono.just(auth);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM