2017-06-29 19 views
0

SpringがJSFで使用されている(PrimeFacesを使用している)プロジェクトがあります。これまではSpring Securityにxml設定を使用していましたが、私はJavaベースの設定に移植することが任されています。Spring Securityのログイン処理のURLがありません

私は今applicationContext.xmlにXML設定から行ってきた:

<!-- Security Config --> 
<security:http security="none" pattern="/javax.faces.resource/**"/> 
<security:http auto-config="true" use-expressions="true"> 
    <security:intercept-url pattern="/login.xhtml" access="permitAll"/> 
    <security:intercept-url pattern="/**" access="permitAll"/> 

    <security:form-login login-page="/login.xhtml" 
     login-processing-url="/do_login" 
     authentication-failure-url="/login.xhtml" 
     authentication-success-handler-ref="authSuccessHandler" 
     username-parameter="email" 
     password-parameter="password"/> 
    <security:logout logout-success-url="/login.xhtml" 
     logout-url="/do_logout" 
     delete-cookies="JSESSIONID"/> 
</security:http> 

<bean id="userDetails" class="com.madmob.madmoney.security.UserDetailsServiceImpl"></bean> 
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> 
    <constructor-arg name="strength" value="10" /> 
</bean> 
<bean id="authSuccessHandler" class="com.madmob.madmoney.security.UserAuthenticationSuccessHandler"></bean> 

<security:authentication-manager> 
    <security:authentication-provider user-service-ref="userDetails"> 
     <security:password-encoder ref="encoder" />  
    </security:authentication-provider> 
</security:authentication-manager> 

web.xmlから次

<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> 
    <dispatcher>FORWARD</dispatcher> 
    <dispatcher>REQUEST</dispatcher> 
</filter-mapping> 

次のJavaベースの構成に:

import javax.sql.DataSource; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.builders.WebSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    UserAuthenticationSuccessHandler authSuccessHandler; 
    @Autowired 
    DataSource dataSource; 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) 
     throws Exception { 
     auth.jdbcAuthentication().usersByUsernameQuery("SELECT email, passowrd, enabled FROM app_user WHERE email = ?") 
     .authoritiesByUsernameQuery("SELECT role_name FROM role WHERE role_id = (SELECT role_id FROM user_role WHERE email = ?)") 
     .dataSource(dataSource).passwordEncoder(new BCryptPasswordEncoder(10)); 
    } 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/javax.faces.resource/**"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable(); 

     http.authorizeRequests().anyRequest().authenticated() 
     .and() 
     .formLogin().loginPage("/login.xhtml").loginProcessingUrl("/do_login") 
     .failureUrl("/login.xhtml").successHandler(authSuccessHandler) 
     .usernameParameter("email").passwordParameter("password").permitAll() 
     .and() 
     .logout().logoutSuccessUrl("/login.xhtml").logoutUrl("/do_logout") 
     .deleteCookies("JSESSIONID"); 

     // temp user add form 
     // TODO remove 
     http.antMatcher("/userForm.xhtml").authorizeRequests().anyRequest().permitAll(); 
    } 
} 

import java.util.EnumSet; 

import javax.servlet.DispatcherType; 

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; 

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer { 

    protected EnumSet<DispatcherType> getSecurityDispatcherTypes() { 
     return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC, DispatcherType.FORWARD); 
    } 
} 

ログインは、XMLベースの設定でうまくいきましたが、私はとTomcatが404を返すログインしようとした場合の切り替え以降:The requested resource is not available.

すべてのページに関係なく、ログインまたはいないのにもアクセス可能です。

以下

は私のログインフォームです:

<h:form id="loginForm" prependId="false" styleClass="panel-body"> 
    <div> 
     <p:inputText id="email" required="true" label="email" 
        value="#{loginBean.email}" styleClass="form-control f-75" 
        placeholder="Email Address"></p:inputText> 
     <h:message for="email" styleClass="validationMsg"/> 
    </div> 
    <div class="spacer"/> 
    <div> 
     <p:password id="password" required="true" label="password" 
        value="#{loginBean.password}" placeholder="Password"></p:password> 
     <h:message for="password" styleClass="validationMsg"/> 

     <h:messages globalOnly="true" styleClass="validationMsg" /> 
    </div> 
    <div class="spacer"/> 
    <p:commandButton id="login" value="Log in" 
        actionListener="#{loginBean.login}" ajax="false"/> 
</h:form> 

と私のバッキングBeanでのログイン方法:

/** 
* Forwards login parameters to Spring Security 
*/ 
public void login(ActionEvent loginEvt){ 
    // setup external context 
    logger.info("Starting login"); 
    ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); 

    // setup dispatcher for spring security 
    logger.info("Setup dispatcher"); 
    RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()) 
      .getRequestDispatcher("/do_login"); 

    try { 
     // forward request 
     logger.info("Forwarding request to spring security"); 
     dispatcher.forward((ServletRequest) context.getRequest(), 
       (ServletResponse) context.getResponse()); 
    } catch (ServletException sEx) { 
     logger.error("The servlet has encountered a problem", sEx); 
    } catch (IOException ioEx) { 
     logger.error("An I/O error has occured", ioEx); 
    } catch (Exception ex) { 
     logger.error("An error has occured", ex); 
    } 

    // finish response 
    FacesContext.getCurrentInstance().responseComplete(); 
} 

これは、Java 1.8、Tomcatの7、春と春のセキュリティ3.2.5上で実行されています、JSF 2.1、Primefaces 5

問題が発生してから試したこと:

  • 最初にSecurityConfigのみを使用していたので、が追加されました。
  • 処理URLと転送先を指定しないで、デフォルトのSpring Security url(j_spring_security_check)を使用して試行します。私は問題を発見し解決
+0

設定なしでSpring Securityをブートストラップします。 'AbstractSecurityWebApplicationInitializer(Class ...)を呼び出す必要があります。デフォルトのno-argsコンストラクタの代わりに 'configurationClasses)'コンストラクタを使用します。あるいは、 'ContextLoaderListener'をロードする別の手段がある場合は、それに設定クラスを追加してください。 –

+0

'ContextLoaderListener'は私の' web.xml'で定義されています。そのコンストラクタを呼び出すと、既にルートアプリケーションコンテキストが存在するため例外が発生します。 '@ EnableWebSecurity'アノテーションがこれを処理すべきであること、あるいは何か不足していることを知っている限り、注意してください。 (パッケージはコンポーネントスキャンの一部ですが、手動でBeanをxmlに手動で定義するときも同じ問題が発生しました) – Vinc

+0

設定がロードされていない場合は、何も効果を持たないアノテーションを必要な数だけ配置できます。だからコンフィグレーションがロードされていることを確認してください(他のものがロードされているにも関わらず、 'springSecurityFilterChain'という名前のBeanが定義されていないことを示すメッセージでアプリケーションの起動に失敗します)。 –

答えて

0

を探しながら

  • 無効CSRF SpringSecurityInitializerから
  • 追加getSecurityDispatcherTypes方法は、web.xmlから
  • 他の様々な小さなものを設定を一致させます。問題は、次のようなものです。

    これは、私の見た目では、私の部分のメソッドの純粋に不正確な連鎖に過ぎませんでした。それだけではなく、予期せぬアクセス動作を発見されていないログイン処理のURLで問題を起こした理由を私は本当に理解していないが、以下のように、私は方法の全体のスニペットを見ていることに変更:

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
        http.csrf().disable() 
        .authorizeRequests().antMatchers("/userForm.xhtml").permitAll() //TODO remove temp user add form 
        .anyRequest().authenticated() 
        .and() 
        .formLogin().loginPage("/login.xhtml").loginProcessingUrl("/do_login") 
        .failureUrl("/login.xhtml").successHandler(authSuccessHandler) 
        .usernameParameter("email").passwordParameter("password").permitAll() 
        .and() 
        .logout().logoutSuccessUrl("/login.xhtml").logoutUrl("/do_logout") 
        .deleteCookies("JSESSIONID"); 
    } 
    

    このコースでも、コメントが指定されているので、userForm.xhtmlは一時的なものなので、私は最初にそれらを分けました。

  • 関連する問題