国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring MVC + Security 4 初體驗(yàn)(Java配置版)

EastWoodYang / 1438人閱讀

摘要:接著,對登錄表單進(jìn)行配置。通過配置表單提交地址,這個地址對應(yīng)的不需要自己寫,會自動攔截提交到此地址請求,將其視為登錄請求。配置完登錄相關(guān)信息之后,接著配置和登出有關(guān)的信息。因?yàn)椴捎蔑L(fēng)格,這里配置響應(yīng)視圖為格式。

spring Version = 4.3.6.RELEASE
springSecurityVersion = 4.2.1.RELEASE
Gradle 3.0 + Eclipse Neno(4.6)

這篇文章同樣是使用的Java配置,而非XML配置,如果你對于Java配置的Spring MVC開發(fā)還不太熟悉,可以先看我這篇文章。

Authority

創(chuàng)建一個 Authority ,實(shí)現(xiàn)自 org.springframework.security.core.GrantedAuthority 類,getAuthority 方法只返回一個表示權(quán)限名稱的字符串,如 AUTH_USER 、 AUTH_ADMIN 、 AUTH_DBA 等。

public class Authority implements GrantedAuthority {
    
    private static final long serialVersionUID = 1L;

    private String authority;

    public Authority() {  }
    public Authority(String authority) {
        this.setAuthority(authority);
    }
    
    @Override
    public String getAuthority() {
        return this.authority;
    }
    public void setAuthority(String authority) {
        this.authority = authority;
    }
}
User

User 類實(shí)現(xiàn)自 org.springframework.security.core.userdetails.UserDetails 接口,包含一組權(quán)限的集合 authorities

public class User implements UserDetails {
    
    private static final long serialVersionUID = 1L;
    
    private String username;
    private String password;
    private List authorities;
    
    @Override
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    
    @Override
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Override
    public Collection getAuthorities() {
        return this.authorities;
    }
    public void setAuthorities(List authorities) {
        this.authorities = authorities;
    }
    
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    @Override
    public boolean isEnabled() {
        return true;
    }
}
UserDetailsService

MyUserDetailsService 實(shí)現(xiàn)了 org.springframework.security.core.userdetails.UserDetailsServiceloadUserByUsername 方法,該方法根據(jù)用戶名查詢符合條件的用戶,若沒有找到符合條件的用戶,必須拋出 UsernameNotFoundException 異常,而不能返回空。這里可以調(diào)用 DAO 層,從數(shù)據(jù)庫查詢用戶,我為了簡單,直接將用戶臨時放到一個常量內(nèi),模擬從數(shù)據(jù)庫查詢用戶。

@Service
public class MyUserDetailsService implements UserDetailsService {
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List userList = Constants.userList;
        for (int i = 0, len = userList.size(); i < len; i++) {
            User user = userList.get(i);
            if (user.getUsername().equals(username)) {
                return user;
            }
        }
        throw new UsernameNotFoundException("用戶不存在!");
    }

}
SecurityConfig

SecurityConfig 類繼承 org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapterWebSecurityConfigurerAdapter 提供了一些默認(rèn)的配置,方便創(chuàng)建一個實(shí)例。

進(jìn)入 configure 方法中,首先允許任何情況下的對csrfTokenApi 的請求,該 API 返回一個 csrfToken ,默認(rèn)情況下除 GETHEADTRACEOPTIONS外,所有請求都必須經(jīng)過 CSRF 認(rèn)證。接下來對不同的API請求設(shè)置不同的權(quán)限,并且確保所有對 /api/ 下的請求都經(jīng)過了認(rèn)證。
這里向 access 方法傳遞的表達(dá)式中的權(quán)限名稱,對應(yīng)上面提到的 Authority 類中 getAuthority 返回的字符串的值,詳細(xì)的表達(dá)式介紹,請移步至這里。

接著,對登錄表單進(jìn)行配置。通過 loginProcessingUrl 配置表單提交地址,這個地址對應(yīng)的API不需要自己寫,Spring Security 會自動攔截提交到此地址請求,將其視為登錄請求。如果希望登錄成功后通過服務(wù)器轉(zhuǎn)發(fā)到其他頁面,可以調(diào)用 successForwardUrl(String forwardUrl) 方法指定跳轉(zhuǎn)的地址,對應(yīng)地,指定失敗后跳轉(zhuǎn)地址的方法是 failureForwardUrl(String forwardUrl)。

這里我使用了RESTful,故不需要配置服務(wù)端的轉(zhuǎn)發(fā),而是配置了另外兩處:successHandlerfailureHandlersuccessHandler 方法接收一個 AuthenticationSuccessHandler 對象,認(rèn)證通過之后,Spring Security 將調(diào)用該對象的 onAuthenticationSuccess 方法,類似地,failureHandler 方法接收一個 AuthenticationFailureHandler 對象,認(rèn)證失敗之后,將調(diào)用該對象的 onAuthenticationFailure 方法。

配置完登錄相關(guān)信息之后,接著配置和登出有關(guān)的信息。和配置登錄表單提交地址類似,這里需要配置登出請求提交地址,這里調(diào)用 logoutUrl 方法,指定登出的鏈接地址,該地址和前面提到的 loginProcessingUrl 都不需要自己寫,這兩個都是全權(quán)交由 Spring Security 來處理。當(dāng)用戶請求 logoutUrl 方法指定的地址時,Spring Security 將對用戶執(zhí)行登出操作。和前面提到的 successForwardUrl 類似,這里提供了 logoutSuccessUrl 方法指定登出成功之后轉(zhuǎn)發(fā)的地址。不過我用了RESTful,就不再調(diào)用此方法,而是調(diào)用 logoutSuccessHandler 傳入 LogoutSuccessHandler 對象,登出成功后將調(diào)用該對象的 onLogoutSuccess 方法。

最后,配置對異常的處理 exceptionHandling ,和上面介紹的 successHandler 、 failureHandler 以及 logoutSuccessHandler 差不多,authenticationEntryPoint 接收一個 AuthenticationEntryPoint 對象,當(dāng)用戶請求的操作需要登錄時,將拋出 AuthenticationException 異常,并且將該異常傳入到 AuthenticationEntryPoint 對象的 commence 方法。
accessDeniedHandler 方法接收一個 AccessDeniedHandler 對象,該對象的 handle 方法將在權(quán)限不足時調(diào)用。

配置完這些,看 configureGlobalSecurity 方法,給 AuthenticationManagerBuilder 配置一個 UserDetailsService 對象,當(dāng)用戶執(zhí)行登錄時,Spring Security 將調(diào)用該對象的 loadUserByUsername 方法,將 username 傳入此方法,根據(jù) username 獲取一個 UserDetails 對象。

另外,由于不能在數(shù)據(jù)庫中保存明文密碼,這里對密碼進(jìn)行 bcrypt 加密后保存,驗(yàn)證密碼是否正確時,需要對用戶輸入的明文密碼進(jìn)行 bcrypt 加密后比較密文是否一致,故這里需要提供一個 BCryptPasswordEncoder 對象。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${api.csrftoken}")
    private String csrfTokenApi;
    
    @Value("${api.login}")
    private String loginApi;
    
    @Value("${api.logout}")
    private String logoutApi;
    
    @Autowired
    private MyUserDetailsService userDetailsService;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers(csrfTokenApi).permitAll()
        .antMatchers("/api/user/**").access("hasAuthority("USER")")
        .antMatchers("/api/admin/**").access("hasAuthority("ADMIN")")
        .antMatchers("/api/dba/**").access("hasAuthority("DBA")")
        .antMatchers("/api/**").fullyAuthenticated()
        .and().formLogin().loginProcessingUrl(loginApi)
        .successHandler(new RestAuthenticationSuccessHandler())
        .failureHandler(new RestAuthenticationFailureHandler())
        .and().logout().logoutUrl(logoutApi)
        .logoutSuccessHandler(new RestLogoutSuccessHandler())
        .and().exceptionHandling().authenticationEntryPoint(new RestAuthenticationEntryPoint())
        .accessDeniedHandler(new RestAccessDeniedHandler());
    }
    
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(11);
    }
}
WebAppConfig

因?yàn)椴捎肦ESTful風(fēng)格,這里配置響應(yīng)視圖為json格式。

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "org.xueliang.springsecuritystudy")
@PropertySource({"classpath:config.properties"})
public class WebAppConfig extends WebMvcConfigurerAdapter {
    
    @Bean
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter(@Autowired MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter, @Autowired ContentNegotiationManager mvcContentNegotiationManager) {
        RequestMappingHandlerAdapter requestMappingHandlerAdapter = new RequestMappingHandlerAdapter();
        requestMappingHandlerAdapter.setMessageConverters(Collections.singletonList(mappingJackson2HttpMessageConverter));
        requestMappingHandlerAdapter.setContentNegotiationManager(mvcContentNegotiationManager);
        return requestMappingHandlerAdapter;
    }
    
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        return new MappingJackson2HttpMessageConverter();
    }
    
    /**
     * 設(shè)置歡迎頁
     * 相當(dāng)于web.xml中的 welcome-file-list > welcome-file
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addRedirectViewController("/", "/index.html");
    }
}
WebAppInitializer

Spring Security 架構(gòu)是完全基于標(biāo)準(zhǔn)的 Servlet 過濾器的,這里我們需要在 WebInitializer 中引入 DelegatingFilterProxy 過濾器。

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain")).addMappingForUrlPatterns(null, false, "/api/*");
        // 靜態(tài)資源映射
        servletContext.getServletRegistration("default").addMapping("*.html", "*.ico");
        super.onStartup(servletContext);
    }

    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[] { WebAppConfig.class };
    }

    @Override
    protected Class[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] { new CharacterEncodingFilter("UTF-8", true) };
    }
}
Source

本文使用到的項(xiàng)目源碼已經(jīng)放到 Github 上,你可以下載后運(yùn)行。

原文鏈接:http://xueliang.org/article/detail/20170302232815082

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/66759.html

相關(guān)文章

  • SpringMVC體驗(yàn)--Code-based

    摘要:最后創(chuàng)建了群方便大家交流,可掃描加入,同時也可加我,共同學(xué)習(xí)共同進(jìn)步,謝謝 創(chuàng)建項(xiàng)目 創(chuàng)建web項(xiàng)目,使用maven webapp模板進(jìn)行構(gòu)建,創(chuàng)建完成后,在pom中引入Spring MVC依賴,如下: org.springframework spring-webmvc 5.0.5.RELEASE javax.servlet ja...

    happyfish 評論0 收藏0
  • 貓頭鷹的深夜翻譯:為什么要使用Spring Boot?

    摘要:初次使用的人往往會困惑,不知道該使用哪種方法。目前來說,團(tuán)隊(duì)推薦使用基于的方法來提供更高的靈活性。配置,從而在應(yīng)用啟動時執(zhí)行腳本來初始化數(shù)據(jù)庫。目前為止我們沒有任何消息需要配置,所以只在文件夾中創(chuàng)建一個空的文件。將配置為,它包含的上下文。 前言 spring是一個用于創(chuàng)建web和企業(yè)應(yīng)用的一個很流行的框架。和別的只關(guān)注于一點(diǎn)的框架不同,Spring框架通過投資并組合項(xiàng)目提供了大量的功能...

    Jaden 評論0 收藏0
  • SpringMVC體驗(yàn)--傳統(tǒng)方式

    摘要:創(chuàng)建項(xiàng)目創(chuàng)建項(xiàng)目,使用模板進(jìn)行構(gòu)建,創(chuàng)建完成后,在中引入依賴,如下引入依賴,使用版本為配置在配置文件中,配置控制器如下指定配置文件,默認(rèn)為,本例配置從中加載容器啟動時加載,若不配置此項(xiàng) 創(chuàng)建項(xiàng)目 創(chuàng)建web項(xiàng)目,使用maven webapp模板進(jìn)行構(gòu)建,創(chuàng)建完成后,在pom中引入Spring MVC依賴,如下: org.springframework spr...

    Nosee 評論0 收藏0
  • Spring體系常用項(xiàng)目一覽

    摘要:的面向的異常遵從通用的異常層次結(jié)構(gòu)。比如以前常用的框架,現(xiàn)在常用的框架包含許多項(xiàng)目,下面挑一些最常用的出來總結(jié)一下。狀態(tài)是流程中事件發(fā)生的地點(diǎn),在流程中通過轉(zhuǎn)移的方式從一個狀態(tài)到另一個狀態(tài),流程的當(dāng)前狀況稱為流程數(shù)據(jù)。 如今做Java尤其是web幾乎是避免不了和Spring打交道了,但是Spring是這樣的大而全,新鮮名詞不斷產(chǎn)生,學(xué)起來給人一種凌亂的感覺,我就在這里總結(jié)一下,理順頭緒...

    OnlyLing 評論0 收藏0
  • SpringBoot+SpringSecurity+jwt整合及體驗(yàn)

    摘要:進(jìn)行下一項(xiàng)配置,為了區(qū)分必須加入。另起一行,以示尊重。這行代碼主要是用于驗(yàn)證,后面再說。然后跑下接口,發(fā)現(xiàn)沒問題,正常打印,說明主體也在上下文中了。說明這會上下文環(huán)境中我們主體不存在。所說以,主體數(shù)據(jù)生命周期是一次請求。 showImg(https://segmentfault.com/img/bVbtoG1?w=1600&h=900); 原來一直使用shiro做安全框架,配置起來相當(dāng)...

    dackel 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<