【问题标题】:PreAuthentication with Spring Security -> Based on URL parametersPreAuthentication with Spring Security -> 基于 URL 参数
【发布时间】:2012-04-11 18:23:21
【问题描述】:

客户希望有以下场景:

客户向 webapp 用户分发带有 2 个参数的链接(webapp 地址)。基于这些变量,用户将在 webapp 中扮演特定的角色。 我不想要任何授权。应该只有身份验证检查会查看这些 url 参数并检查它们是否有效并将用户连接到适当的角色。

我怎么能意识到这一点?!是否已有可用的解决方案?

谢谢!

问候马蒂亚斯

【问题讨论】:

    标签: url authentication spring-security


    【解决方案1】:

    我已经解决了这个问题。 对于那些有兴趣的人......

    web.xml

    <!-- ===== SPRING CONFIG ===== -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
            /WEB-INF/applicationContext-security.xml
        </param-value>
    </context-param>
    

    applicationContext.xml

    <context:component-scan base-package="at.beko.rainstar2" />
    
    <tx:annotation-driven transaction-manager="transactionManager" />
    

    applicationContext-security.xml

    <!-- Configuring security not finished!! -->
    <http create-session="never" use-expressions="true" auto-config="false"
        entry-point-ref="preAuthenticatedProcessingFilterEntryPoint">
        <intercept-url pattern="/authError.xhtml" access="permitAll" />
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
        <custom-filter position="PRE_AUTH_FILTER" ref="preAuthFilter" />
        <session-management session-fixation-protection="none" />
    </http>
    
    <beans:bean id="userDetailsServiceImpl"
        class="at.beko.rainstar2.service.impl.UserDetailsServiceImpl" />
    
    <beans:bean id="preAuthenticatedProcessingFilterEntryPoint"
        class="at.beko.rainstar2.model.LinkForbiddenEntryPoint" />
    
    <beans:bean id="preAuthenticationProvider"
        class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <beans:property name="preAuthenticatedUserDetailsService"
            ref="userDetailsServiceImpl" />
    </beans:bean>
    
    <beans:bean id="preAuthFilter"
        class="at.beko.rainstar2.service.filter.UrlParametersAuthenticationFilter">
        <beans:property name="authenticationManager" ref="appControlAuthenticationManager" />
    </beans:bean>
    
    <authentication-manager alias="appControlAuthenticationManager">
        <authentication-provider ref="preAuthenticationProvider" />
    </authentication-manager>
    

    LinkForbiddenEntryPoint.java

    public class LinkForbiddenEntryPoint implements AuthenticationEntryPoint {
    
    @Override
    public void commence(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.sendRedirect("/rainstar2-webapp/authError.xhtml");
    }
    

    }

    UrlParametersAuthenticationFilter.java

    public class UrlParametersAuthenticationFilter extends
        AbstractPreAuthenticatedProcessingFilter {
    
    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        if (request.getParameterMap().size() == 2) {
            return true;
        }
        return false;
    }
    
    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
        String[] credentials = new String[2];
        credentials[0] = request.getParameter("param1");
        credentials[1] = request.getParameter("param2");
        return credentials;
    }
    

    }

    UserDetailsS​​erviceImpl.java

    @SuppressWarnings("deprecation")
    public class UserDetailsServiceImpl implements
        AuthenticationUserDetailsService<Authentication> {
    
    @Override
    public UserDetails loadUserDetails(Authentication token)
            throws UsernameNotFoundException {
        UserDetails userDetails = null;
    
                String[] credentials = (String[]) token.getPrincipal();
        boolean principal = Boolean.valueOf(token.getCredentials().toString());
    
        if (credentials != null && principal == true) {
            String name = credentials[0];
            if ("admin".equalsIgnoreCase(name)) {
                userDetails = getAdminUser(name);
            } else if ("händler".equalsIgnoreCase(name)) {
                userDetails = getRetailerUser(name);
            } else if ("user".equalsIgnoreCase(name)) {
                userDetails = getUserUser(name);
            }
        }
    
        if (userDetails == null) {
            throw new UsernameNotFoundException("Could not load user : "
                    + token.getName());
        }
    
        return userDetails;
    }
    
    private UserDetails getAdminUser(String username) {
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
        grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_RETAILER"));
        grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
        return new User(username, "notused", true, true, true, true,
                grantedAuthorities);
    }
    
    private UserDetails getRetailerUser(String username) {
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
        grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_RETAILER"));
        return new User(username, "notused", true, true, true, true,
                grantedAuthorities);
    }
    
    private UserDetails getUserUser(String username) {
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
        return new User(username, "notused", true, true, true, true,
                grantedAuthorities);
    }
    

    }

    【讨论】:

    • 我正在尝试实施您的解决方案,但我在 String[] credentials = (String[]) token.getPrincipal(); 的 UserDetailsS​​erviceImpl 类中得到了验证;说明我应该获得凭据。
    • 这篇相关文章帮我实现了这个https://stackoverflow.com/questions/12478589/springsecurity-custom-automatic-authentication
    【解决方案2】:

    我在类似情况下解决此问题的方法是使用 servlet 过滤器来获取参数。我建议扩展 org.springframework.web.filter.GenericFilterBean。

    根据这些参数,创建某种身份验证对象(例如令牌),该对象可以传递到 AuthenticationManager 中,您可以自动装配(或通过其他方法获取)。

    然后,您将需要一个 AuthenticationProvider 来处理您的身份验证对象并生成一个带有 GrantedAuthority 集合的 UserDetails 对象,以满足您希望用户拥有的特定角色。

    【讨论】:

      猜你喜欢
      • 2011-12-22
      • 2017-05-23
      • 2012-12-14
      • 2019-06-27
      • 1970-01-01
      • 2016-06-03
      • 2019-06-12
      • 2019-01-07
      • 2015-03-06
      相关资源
      最近更新 更多