Spring security login-free dynamic configuration scheme 2



A previous article talked about how to implement the login-free dynamic configuration scheme, using reflection to implement it, which smacks of black magic. Here is another scheme


spring-security-config-4.2.3.RELEASE-sources.jar! /org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationConfigurer.java

public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
        AbstractInterceptUrlConfigurer<ExpressionUrlAuthorizationConfigurer<H>, H> {
    static final String permitAll = "permitAll";
    private static final String denyAll = "denyAll";
    private static final String anonymous = "anonymous";
    private static final String authenticated = "authenticated";
    private static final String fullyAuthenticated = "fullyAuthenticated";
    private static final String rememberMe = "rememberMe";

    private final ExpressionInterceptUrlRegistry REGISTRY;

         * Specify that URLs are allowed by anyone.
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further
         * customization
        public ExpressionInterceptUrlRegistry permitAll() {
            return access(permitAll);

        public ExpressionInterceptUrlRegistry access(String attribute) {
            if (not) {
                attribute = "!" + attribute;
            interceptUrl(requestMatchers, SecurityConfig.createList(attribute));
            return ExpressionUrlAuthorizationConfigurer.this.REGISTRY;

        private void interceptUrl(Iterable<? extends RequestMatcher> requestMatchers,
            Collection<ConfigAttribute> configAttributes) {
        for (RequestMatcher requestMatcher : requestMatchers) {
            REGISTRY.addMapping(new AbstractConfigAttributeRequestMatcherRegistry.UrlMapping(
                    requestMatcher, configAttributes));

Permitol adds the attribute “Permitol” and the corresponding requestMatchers to REGISTRY

Train of thought

public class SecurityConfig extends WebSecurityConfigurerAdapter {
    public void configure(HttpSecurity http) throws Exception {
                .antMatchers("/css/**", "/js/**","/fonts/**").permitAll()

This article focuses on this anyRequest().authenticated () . You can see that requests that are not configured with permitAll all require the level of authenticated, while anonymousAuthenticationFilter sets the anonymous level as Anonymous.

So our train of thought came, creating a new filter and inserting it before AnonymousAuthenticationFilter. The login-free setting was authenticated


public class DemoFilter extends GenericFilterBean {

    private Object principal = "annoUser";

    private List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANNO");

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        private final Map<String,HttpMethod[]> annoPatternMap = new HashMap<String,HttpMethod[]>(){{
        //for demo, you can change it and read from db or else
        put("/index/demo",new HttpMethod[]{HttpMethod.GET});
        String uri = ((HttpServletRequest) servletRequest).getRequestURI();
            if(SecurityContextHolder.getContext().getAuthentication() == null){
                        createAuthentication((HttpServletRequest) servletRequest));
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            System.out.println(auth == null);
            if(auth != null && auth instanceof UsernamePasswordAuthenticationToken){
        filterChain.doFilter(servletRequest, servletResponse);
    protected Authentication createAuthentication(HttpServletRequest request) {
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                principal, "N/A", authorities);

        return auth;

A fake UserNamePasswordAuthenticationToken was created here.

One thing to note here is that when judging that it is not a configured url that allows anonymous access, if the previous token was set by us, it needs to be cleared again to prevent unauthorized access to other unconfigured urls after acquiring the session once accessing the anonymous URL.

Configure filter

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    protected void configure(HttpSecurity http) throws Exception {
                .addFilterBefore(new DemoFilter(),AnonymousAuthenticationFilter.class)
                .antMatchers("/css/**", "/js/**","/fonts/**").permitAll()

    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

Before AnonymousAuthenticationFilter, set the authentication in SecurityContextHolder in advance.


This is basically a success, but there are several points to note:

  • The custom filter may have the problem of executing it twice, which will be discussed in the following article.
  • The acquired uri cannot handle the case of pathvariable, and needs to be handled according to url pattern, which will be described later.