SecurityExpressionRoot中的Authentication对象中的匿名用户

时间:2019-07-16 08:39:46

标签: java spring spring-security spring-security-ldap

我有一个Spring Boot应用程序,该应用程序应提供AD身份验证,并使用存储在数据库中的权限来授权请求​​。 Ldap身份验证工作正常。我在Spring Security Java Configuration类中放入的授权设置有问题,因为它不起作用。我以在数据库中具有SYSTEM_LOGIN权限的用户身份登录,但 .antMatchers(“ / requests / **”)。hasAuthority(“ SYSTEM_LOGIN”)不允许他访问/ requests URL(带有403禁止响应)

我尝试实现CustomSecurityExpressionRoot和CustomSecurityExpressionHandler,但没有帮助。可能我以错误的方式将其注入配置...

这是我的SpringSecurity Java配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Value("${ldap.urls:ldap://host:port/dc=test,dc=local}")
    private String ldapUrls;

    @Value("${ldap.filter:(&(objectClass=user)(sAMAccountName={0}))}")
    private String ldapFilter;

    @Value("${ldap.managerDn:test}")
    private String ldapManagerDn;

    @Value("${ldap.managerPassword:testpass}")
    private String ldapManagerPassword;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/login*").permitAll()
                .antMatchers("/requests/**").hasAuthority("SYSTEM_LOGIN")
                .anyRequest().permitAll()
                .and()
                .logout().deleteCookies("JSESSIONID")
                .and()
                .csrf().disable();
    }



@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    CustomJdbcUserDetailsService customJdbcUserDetailsService = new CustomJdbcUserDetailsService();
    customJdbcUserDetailsService.setDataSource(dataSource);    
    CustomLdapAuthoritiesPopulator customLdapAuthoritiesPopulator = new CustomLdapAuthoritiesPopulator(customJdbcUserDetailsService);
    DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapUrls);
    contextSource.setUserDn(ldapManagerDn);
    contextSource.setPassword(ldapManagerPassword);
    contextSource.setReferral("follow");
    contextSource.afterPropertiesSet();
    LdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch("", ldapFilter, contextSource);
    BindAuthenticator bindAuthenticator = new BindAuthenticator(contextSource);
    bindAuthenticator.setUserSearch(ldapUserSearch);
    LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator);
    auth.authenticationProvider(ldapAuthenticationProvider);
auth.ldapAuthentication().ldapAuthoritiesPopulator(customLdapAuthoritiesPopulator).
userDnPatterns("uid={0},ou=users").contextSource(contextSource);

}

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public AuthTokenService tokenService() {
        return new AuthTokenService();
    }

    @Bean
    public CustomSecurityExpressionHandler expressionHandler() {
        return new CustomSecurityExpressionHandler();
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

这是登录控制器:

@Slf4j
@RestController
public class LoginController {

    private static Map<String, Object> defaultMapToReturn = new HashMap<>();

    @Autowired
    private ADAuthService authenticationService;

    @RequestMapping(
            value = "/login",
            method = RequestMethod.POST)
    public Map<String, Object> getLogin(@RequestBody UIAuthenticationRequest request) throws TokenAlreadyExistsException {
        AuthToken authToken = authenticationService.authenticateUser(request);
        defaultMapToReturn.put("token", authToken.getTokenValue());
        defaultMapToReturn.put("userPermissions", authToken.getUser().getAuthorities());      
        return defaultMapToReturn;
    }

服务代码:

@Service
public class ADAuthService {
    @Autowired
    private SuidRolesRepository rolesRepository;

    @Autowired
    private PermissionRepository permsRepository;

    /**
     * Authentication Manager from spring security context.
     */
    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * AuthTokenService which validates tokens.
     */
    private AuthTokenService authTokenService;

    @Autowired
    @Qualifier("sessionRegistry")
    private SessionRegistry sessionRegistry;
    /**
     * Constructor injection of AuthenticationManager and AuthTokenService
     */
    @Autowired
    public ADAuthService(AuthenticationManager authenticationManager, AuthTokenService authTokenService) {
        this.authenticationManager = authenticationManager;
        this.authTokenService = authTokenService;
    }

    public AuthToken authenticateUser(UIAuthenticationRequest request) throws TokenAlreadyExistsException {
        List<SuidRole> roles = rolesRepository.findByUser(request.getUsername());
        List auths = new ArrayList(getPermissions(roles));
        final Authentication authentication = authenticationManager.authenticate(
               new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword(), auths)
        );

        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authentication);
        SecurityContextHolder.setContext(context);


        UserDetails userDetails = new ADUserDetails(
                request.getUsername(),
                request.getPassword(),
                getPermissions(roles)
        );

        AuthToken authToken = new AuthToken(UUID.randomUUID().toString(), LocalDateTime.now(), userDetails);
        authTokenService.storeToken(authToken);
        return authToken;
    }

在调试时,我看到当我使用url / requests / **调用请求时,它转到SecurityExpressionRoot类,在方法hasAuthority()中,但是SecurityExpressionRoot内部的身份验证对象具有主体=“ anonymousUser”,并且在权限中仅列出了“ ROLE_ANONYMOUS”,其中显然不是我所期望的。

0 个答案:

没有答案