java - Spring security spring webflow 如何使用用户角色成功登录页面后重定向?

标签 java spring spring-mvc redirect spring-webflow

我是 Spring 框架的初学者,我的应用程序在成功登录后重定向时遇到问题

  1. 我在网上播放此视频来开发我的应用程序 https://www.youtube.com/watch?v=94OvXuwqnGc
  2. 当我想在成功登录后重定向我的应用程序时,我发现一个问题: 如果用户有“ROLE_ADMIN”,他们应该重定向到 accountAdmin.xhtml,否则如果用户有“ROLE_USER”,他们应该重定向到 accountUser.xml;但他们将所有用户重定向到 accountAdmin.xhtml

我的应用程序的结构如下: app structure

这是我的 main-flow.xml:

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/webflow
        http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

    <var name="user" class="com.ismart.itubibe.entities.UserEntity"/>

    <view-state id="welcome" view="welcome.xhtml" model="user">
        <transition on="newUser" to="signUp"/>
        <transition on="signIn" to="finish">
            <evaluate expression="userAuthenticationProviderService.processUserAuthentication(user)"/>
        </transition>
    </view-state>

    <view-state id="signUp" view="signUp.xhtml" model="user">
        <transition on="backToSignIn" to="welcome"/>
        <transition on="signUp" to="authentication">
            <evaluate expression="userServices.createUser(user)"/>
        </transition>
    </view-state>

    <action-state id="authentication">
        <evaluate expression="userAuthenticationProviderService.processUserAuthentication(user)"/>
        <transition on="yes" to="finish" />
        <transition on="no" to="welcome" />
    </action-state>

    <end-state id="finish" view="externalRedirect:account" />

</flow>

我的安全配置.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security.xsd">

    <security:http auto-config="true">

        <security:form-login login-page="/app/main" default-target-url="/app/account" authentication-success-handler-ref="customAuthenticationSuccessHandler" />
        <security:logout logout-url="/app/logout" logout-success-url="/app/main" />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userServices">
            <security:password-encoder hash="md5" />
        </security:authentication-provider>
    </security:authentication-manager>
    <bean id="customAuthenticationSuccessHandler" class="com.ismart.test.services.impl.CustomAuthenticationSuccessHandler"/>
    <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userServices" />
        <property name="hideUserNotFoundExceptions" value="false" />
    </bean>

    <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
        <constructor-arg>
            <ref bean="daoAuthenticationProvider" />
        </constructor-arg>
    </bean>

</beans>

我的帐户-flow.xml:

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/webflow
        http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

    <secured attributes="ROLE_USER, ROLE_ADMIN" match="any"/>

    <view-state id="admin" view="accountAdmin.xhtml">
    </view-state>

    <view-state id="user" view="accountUser.xhtml">
    </view-state>

</flow>

我的加载用户详细信息方法:

public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

                UserEntity user = userDao.loadUserByUserName(userName);

                if(user == null){
                    throw new UsernameNotFoundException(String.format("Etulisateur introuvable '%s'", userName)); 
                }

                Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

                authorities.add(new SimpleGrantedAuthority(user.getUserType()));

                User userDetails = new User(user.getUserName(), user.getPassWord(), authorities);

                return userDetails;
            }

认证方法

public boolean processUserAuthentication(UserEntity user) {
        try {
            Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassWord());
            Authentication result = authenticationManager.authenticate(request);
            SecurityContextHolder.getContext().setAuthentication(result);
            return true;
        } catch (AuthenticationException e) {

            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "Sorry!!"));
            return false;
        }
    }

我的 CustomAuthenticationSuccessHandler:

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication) throws IOException,
            ServletException {
         Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 

        /*Set target URL to redirect*/
        String targetUrl = determineTargetUrl(auth); 
        redirectStrategy.sendRedirect(request, response, targetUrl);
    }

    protected String determineTargetUrl(Authentication authentication) {
        Set<String> authorities = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
        if (authorities.contains("ROLE_ADMIN")) {
            return "/accountAdmin.xhtml";
        } else if (authorities.contains("ROLE_USER")) {
            return "/accountUser.xhtml";
        } else {
            throw new IllegalStateException();
        }
    }

    public RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }

    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }
}

和我的 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <display-name>iTubibe</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>Resources Servlet</servlet-name>
        <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Resources Servlet</servlet-name>
        <url-pattern>/resources/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>charEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>charEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>excite-bike</param-value>
    </context-param>
    <context-param>
        <param-name>primefaces.FONT_AWESOME</param-name>
        <param-value>true</param-value>
    </context-param>
    <!-- Spring security filters -->
    <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>
</web-app>

你能告诉我我的错误在哪里,以及我如何继续思考

最佳答案

您的帐户流程:

<secured attributes="ROLE_USER, ROLE_ADMIN" match="any"/>

<view-state id="admin" view="accountAdmin.xhtml">
</view-state>

<view-state id="user" view="accountUser.xhtml">
</view-state>

没有任何条件。对于 ROLE_USER 和 ROLE_ADMIN,第一个 View 状态“admin”将在调用流程时呈现。

您需要从决策状态开始:

<secured attributes="ROLE_USER, ROLE_ADMIN" match="any"/>

<decision-state id="userOrAdmin">
    <if test="userAuthenticationProviderService.isAdmin(currentUser)" then="admin" else="user"/>
</decision-state>

<view-state id="admin" view="accountAdmin.xhtml">
</view-state>

<view-state id="user" view="accountUser.xhtml">
</view-state>

您需要创建 userAuthenticationProviderService.isAdmin(principal) 方法来检查用户是否具有管理员角色。我认为您不能直接在流程中执行此操作。

关于java - Spring security spring webflow 如何使用用户角色成功登录页面后重定向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37100437/

相关文章:

java - 当我们有相同HashCode和差异等于的Entry对象的链接列表时,HashMap存储桶不被使用

java - 为什么在新日期的代码中使用linethrough

java - 如何确保我不会同时在两个线程之间共享同一个套接字?

model-view-controller - 数据模型中的Spring Formatters,这是否违反了MVC?有更好的选择吗?

javascript - Spring:从 JSTL(forEach) 转换为 angular.js(ng-repeat)

java - 使用 Maven 的 SpringMVC 和 Hibernate

java - 使用 xuggler 将 BufferedImages 合并到视频中

java - 找不到任何 <webflow> 标签

java - 使用 Java 类中的 file.properties 参数访问属性

java - 如何对几个实体使用两种不同的 Hibernate 缓存策略