使用java 編程的註解的方式定製spring security

上一批博客 介紹了用 xml配置的方式來使用spring security
現在改造成完全使用註解的方式進行 定製 spring security

  1. 編程方式替換 在web.xml中定義的spring 的 filterChain

    <!-- spring security -->
    <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>
    <!-- end -->
    

    用java 代碼來實現是:定義一個 SecurityWebApplicationInitializer 類來繼承AbstractSecurityWebApplicationInitializer

    /**
     * @Title: SecurityWebApplicationInitializer.java
     * @Package com.ninelephas.whale.springsecurity.configuration
     * @Description: TODO
     * Copyright: Copyright (c) 2016
     * Company:九象網絡科技(上海)有限公司
     * 
     * @author roamerxv
     * @date 2016年9月6日 下午7:04:47
     * @version V1.0.0
     */
    
    package com.ninelephas.whale.springsecurity.configuration;
    
    import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
    
    /**
      * @ClassName: SecurityWebApplicationInitializer
      * @Description: TODO
      * @author Comsys-roamerxv
      * @date 2016年9月6日 下午7:04:47
      *
      */
    
    public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
    
    }
  2. 編程方式實現在 applicationContext-security.xml 中定義的 http 部分

    <http auto-config="false">
            <intercept-url pattern="/" access="permitAll" />
            <intercept-url pattern="/admin**" access="hasRole('ADMIN')" />
             <intercept-url pattern="/workflow/***" access="hasRole('ADMIN')" />
            自定義登錄的界面
            <form-login login-page="/views/login.jsp" username-parameter="username" password-parameter="password"/>
            自定登錄的filter
            <custom-filter before="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter" />
            自定退出的filter
            <custom-filter before="LOGOUT_FILTER" ref="customLogoutFilter" />
        </http>

    用java 代碼來實現是:定義一個 SecurityConfiguration 類來繼承WebSecurityConfigurerAdapter

    “`
    /**

    • @Title: SecurityConfiguration.java
    • @Package com.ninelephas.whale.springsecurity.configuration
    • @Description: TODO
    • Copyright: Copyright (c) 2016
    • Company:九象網絡科技(上海)有限公司

      • @author roamerxv
    • @date 2016年9月7日 下午12:17:47
    • @version V1.0.0
      */

package com.ninelephas.whale.springsecurity.configuration;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;

import com.ninelephas.whale.springsecurity.CustomLoginSuccessHandler;
import com.ninelephas.whale.springsecurity.CustomLogoutFilter;
import com.ninelephas.whale.springsecurity.CustomUsernamePasswordAuthenticationFilter;

/**
* @ClassName: SecurityConfiguration
* @Description: TODO
* @author Comsys-roamerxv
* @date 2016年9月7日 下午12:17:47
*
*/

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
/**
* Logger for this class
*/
private static final Logger logger = LogManager.getLogger(SecurityConfiguration.class.getName());

@Autowired
CustomUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter;

// @Autowired
// CustomLogoutFilter customLogoutFilter;

@Autowired
CustomLoginSuccessHandler customLoginSuccessHandler;

// 這裏要分配注入一個 AuthenticationManagerBuilder的實例
@Autowired
AuthenticationManagerBuilder authenticationManagerBuilder;

// 這裏要注入這個方法。
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    logger.debug("configureGlobal(AuthenticationManagerBuilder) - start"); //$NON-NLS-1$
    this.authenticationManagerBuilder.inMemoryAuthentication().withUser("user").password("user").roles("USER");
    this.authenticationManagerBuilder.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
    logger.debug("configureGlobal(AuthenticationManagerBuilder) - end"); //$NON-NLS-1$
}


@Override
protected void configure(HttpSecurity http) throws Exception {
    logger.debug("configure(HttpSecurity) - start"); //$NON-NLS-1$

    http.authorizeRequests()
        .antMatchers("/").access("permitAll")
        .antMatchers("/admin**").access("hasRole('ADMIN')")
        .antMatchers("/workflow/***").access("hasRole('ADMIN')")
        .and().formLogin().loginPage("/views/login.jsp").successHandler(customLoginSuccessHandler)
        .usernameParameter("username").passwordParameter("password")
        .and().csrf()
        .and().exceptionHandling()
        .and().addFilterBefore(customUsernamePasswordAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        //.addFilterBefore(customLogoutFilter, LogoutFilter.class);

    logger.debug("configure(HttpSecurity) - end"); //$NON-NLS-1$
}


// 這裏要用@Bean註解這個方法,以便容器調用獲取實例   AuthenticationManager 實例
@Bean
public AuthenticationManager authenticationManager() throws Exception {
    logger.debug("authenticationManager() - start"); //$NON-NLS-1$
    logger.debug("authenticationManager() - end"); //$NON-NLS-1$
    return this.authenticationManagerBuilder.build();
}

}

```

3. 編程方式實現在 applicationContext-security.xml 中定義的 指定登錄filter的實現類

<beans:bean id="customUsernamePasswordAuthenticationFilter" class="com.ninelephas.whale.springsecurity.CustomUsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

用java 代碼來實現是:定義一個 CustomUsernamePasswordAuthenticationFilter 類來實現UsernamePasswordAuthenticationFilter

```
/**
 * @Title: CustomLoginFilter.java
 * @Package com.ninelephas.whale.springsecurity
 * @Description: TODO
 *               Copyright: Copyright (c) 2016
 *               Company:九象網絡科技(上海)有限公司
 * 
 * @author roamerxv
 * @date 2016年9月6日 上午11:23:31
 * @version V1.0.0
 */

package com.ninelephas.whale.springsecurity;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

/**
 * @ClassName: CustomLoginFilter
 * @Description: TODO
 * @author Comsys-roamerxv
 * @date 2016年9月6日 上午11:23:31
 *
 */
@Component
public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    /**
     * Logger for this class
     */
    private static final Logger logger = LogManager.getLogger(CustomUsernamePasswordAuthenticationFilter.class.getName());


    /*
      * <p>Title: setAuthenticationManager</p>
      * <p>指定AuthenticationManager</p>
      * @param authenticationManager
      * @see org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter#setAuthenticationManager(org.springframework.security.authentication.AuthenticationManager)
      */

    @Autowired
    @Override
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        logger.debug("setAuthenticationManager(AuthenticationManager) - start"); //$NON-NLS-1$
        super.setAuthenticationManager(authenticationManager);
        logger.debug("setAuthenticationManager(AuthenticationManager) - end"); //$NON-NLS-1$
    }

    /*
      * <p>Title: attemptAuthentication</p>
      * <p>登錄驗證做的出來: </p>
      * @param request
      * @param response
      * @return
      * @throws AuthenticationException
      * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
      */

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        logger.debug("attemptAuthentication(HttpServletRequest, HttpServletResponse) - start"); //$NON-NLS-1$

        logger.debug("attemptAuthentication(HttpServletRequest, HttpServletResponse) - end"); //$NON-NLS-1$
        return super.attemptAuthentication(request, response);
    }

    /*
      * <p>Title: successfulAuthentication</p>
      * <p>登錄成功: </p>
      * @param request
      * @param response
      * @param chain
      * @param authResult
      * @throws IOException
      * @throws ServletException
      * @see org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter#successfulAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain, org.springframework.security.core.Authentication)
      */

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
        HttpServletResponse response,
        FilterChain chain,
        Authentication authResult) throws IOException, ServletException {
        logger.debug("successfulAuthentication(HttpServletRequest, HttpServletResponse, FilterChain, Authentication) - start"); //$NON-NLS-1$
        super.successfulAuthentication(request, response, chain, authResult);
        logger.debug(new StringBuffer("登錄成功!用戶是:").append(authResult.getName()));
        request.getSession().setAttribute("user", authResult.getName());
        logger.debug("successfulAuthentication(HttpServletRequest, HttpServletResponse, FilterChain, Authentication) - end"); //$NON-NLS-1$
    }

    /*
      * <p>Title: unsuccessfulAuthentication</p>
      * <p>登錄失敗: </p>
      * @param request
      * @param response
      * @param failed
      * @throws IOException
      * @throws ServletException
      * @see org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter#unsuccessfulAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.AuthenticationException)
      */

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request,
        HttpServletResponse response, AuthenticationException failed)
        throws IOException, ServletException {
        logger.debug("unsuccessfulAuthentication(HttpServletRequest, HttpServletResponse, AuthenticationException) - start"); //$NON-NLS-1$
        super.unsuccessfulAuthentication(request, response, failed);
        logger.debug("登錄失敗!");
        logger.debug("unsuccessfulAuthentication(HttpServletRequest, HttpServletResponse, AuthenticationException) - end"); //$NON-NLS-1$
    }

}

```

* 注意!!! *

在xml配置中customUsernamePasswordAuthenticationFilter 這部分需要指定authenticationManager ,並且 是通過

<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="user" password="user" authorities="ROLE_USER" />
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>

來指定的。所以在SecurityConfiguration.java 文件中需要注意着幾個地方
a. 定義一個
@Autowired
AuthenticationManagerBuilder authenticationManagerBuilder;
變量
b. 在配置的函數裏面 設置這個變量

    // 這裏要注入這個方法。
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        logger.debug("configureGlobal(AuthenticationManagerBuilder) - start"); //$NON-NLS-1$
                            this.authenticationManagerBuilder.inMemoryAuthentication().withUser("user").password("user").roles("USER");
        this.authenticationManagerBuilder.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
        logger.debug("configureGlobal(AuthenticationManagerBuilder) - end"); //$NON-NLS-1$
    }

c. 用Bean來註解authenticationManager的方法來返回這個 AuthenticationManager

    // 這裏要用@Bean註解這個方法,以便容器調用獲取實例   AuthenticationManager 實例
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        logger.debug("authenticationManager() - start"); //$NON-NLS-1$
        AuthenticationManager authenticationManager =  this.authenticationManagerBuilder.build();
        logger.debug(new StringBuffer("AuthenticationManager設置成功,對象指針是:").append(authenticationManager));
        logger.debug("authenticationManager() - end"); //$NON-NLS-1$
        return authenticationManager;
    }

d. 在CustomUsernamePasswordAuthenticationFilter.java 中設置這個變量

    @Autowired
    @Override
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        logger.debug("setAuthenticationManager(AuthenticationManager) - start"); //$NON-NLS-1$
        super.setAuthenticationManager(authenticationManager);
        logger.debug("setAuthenticationManager(AuthenticationManager) - end"); //$NON-NLS-1$
    }

    1. 5.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章