真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java中SpringSecurity的實(shí)例詳解

java中Spring Security的實(shí)例詳解

創(chuàng)新互聯(lián)客戶idc服務(wù)中心,提供成都服務(wù)器托管、成都服務(wù)器、成都主機(jī)托管、成都雙線服務(wù)器等業(yè)務(wù)的一站式服務(wù)。通過各地的服務(wù)中心,我們向成都用戶提供優(yōu)質(zhì)廉價(jià)的產(chǎn)品以及開放、透明、穩(wěn)定、高性價(jià)比的服務(wù),資深網(wǎng)絡(luò)工程師在機(jī)房提供7*24小時(shí)標(biāo)準(zhǔn)級技術(shù)保障。

spring security是一個(gè)多方面的安全認(rèn)證框架,提供了基于JavaEE規(guī)范的完整的安全認(rèn)證解決方案。并且可以很好與目前主流的認(rèn)證框架(如CAS,中央授權(quán)系統(tǒng))集成。使用spring security的初衷是解決不同用戶登錄不同應(yīng)用程序的權(quán)限問題,說到權(quán)限包括兩部分:認(rèn)證和授權(quán)。認(rèn)證是告訴系統(tǒng)你是誰,授權(quán)是指知道你是誰后是否有權(quán)限訪問系統(tǒng)(授權(quán)后一般會(huì)在服務(wù)端創(chuàng)建一個(gè)token,之后用這個(gè)token進(jìn)行后續(xù)行為的交互)。

spring security提供了多種認(rèn)證模式,很多第三方的認(rèn)證技術(shù)都可以很好集成:

  • Form-based authentication (用于簡單的用戶界面)
  • OpenID 認(rèn)證
  • Authentication based on pre-established request headers (such as Computer - Associates Siteminder)根據(jù)預(yù)先建立的請求頭進(jìn)行驗(yàn)證
  • JA-SIG Central Authentication Service ( CAS, 一個(gè)開源的SSO系統(tǒng))
  • Java Authentication and Authorization Service (JAAS)

這里只列舉了部分,后面會(huì)重點(diǎn)介紹如何集成CAS,搭建自己的認(rèn)證服務(wù)。

在spring boot項(xiàng)目中使用spring security很容易,這里介紹如何基于內(nèi)存中的用戶和基于數(shù)據(jù)庫進(jìn)行認(rèn)證。

準(zhǔn)備

pom依賴:


        org.springframework.boot
        spring-boot-starter-security
        1.5.1.RELEASE
      

配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Bean
  public UserDetailsService userDetailsService() {
    return new CustomUserDetailsService();
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("rhwayfun").password("1209").roles("USERS")
        .and().withUser("admin").password("123456").roles("ADMIN");
    //auth.jdbcAuthentication().dataSource(securityDataSource);
    //auth.userDetailsService(userDetailsService());
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()//配置安全策略
        //.antMatchers("/","/index").permitAll()//定義/請求不需要驗(yàn)證
        .anyRequest().authenticated()//其余的所有請求都需要驗(yàn)證
        .and()
        .formLogin()
        .loginPage("/login")
        .defaultSuccessUrl("/index")
        .permitAll()
        .and()
        .logout()
        .logoutSuccessUrl("/login")
        .permitAll();//定義logout不需要驗(yàn)證

    http.csrf().disable();
  }

}

這里需要覆蓋WebSecurityConfigurerAdapter的兩個(gè)方法,分別定義什么請求需要什么權(quán)限,并且認(rèn)證的用戶密碼分別是什么。

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
  /**
   * 統(tǒng)一注冊純RequestMapping跳轉(zhuǎn)View的Controller
   */
  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/login").setViewName("/login");
  }
}

添加登錄跳轉(zhuǎn)的URL,如果不加這個(gè)配置也會(huì)默認(rèn)跳轉(zhuǎn)到/login下,所以這里還可以自定義登錄的請求路徑。

登錄頁面:



<%--<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>--%>



  
  Welcome SpringBoot
  
  





基于內(nèi)存

SecurityConfig這個(gè)配置已經(jīng)是基于了內(nèi)存中的用戶進(jìn)行認(rèn)證的,

auth.inMemoryAuthentication()//基于內(nèi)存進(jìn)行認(rèn)證
.withUser("rhwayfun").password("1209")//用戶名密碼
.roles("USERS")//USER角色
        .and()
        .withUser("admin").password("123456").roles("ADMIN");//ADMIN角色

訪問首頁會(huì)跳轉(zhuǎn)到登錄頁面這成功,使用配置的用戶登錄會(huì)跳轉(zhuǎn)到首頁。

基于數(shù)據(jù)庫

基于數(shù)據(jù)庫會(huì)復(fù)雜一些,不過原理是一致的只不過數(shù)據(jù)源從內(nèi)存轉(zhuǎn)到了數(shù)據(jù)庫。從基于內(nèi)存的例子我們大概知道spring security認(rèn)證的過程:從內(nèi)存查找username為輸入值得用戶,如果存在著驗(yàn)證其角色時(shí)候匹配,比如普通用戶不能訪問admin頁面,這點(diǎn)可以在controller層使用@PreAuthorize("hasRole('ROLE_ADMIN')")實(shí)現(xiàn),表示只有admin角色的用戶才能訪問該頁面,spring security中角色的定義都是以ROLE_開頭,后面跟上具體的角色名稱。

如果要基于數(shù)據(jù)庫,可以直接指定數(shù)據(jù)源即可:

auth.jdbcAuthentication().dataSource(securityDataSource);

只不過數(shù)據(jù)庫標(biāo)是spring默認(rèn)的,包括三張表:users(用戶信息表)、authorities(用戶角色信息表)

以下是查詢用戶信息以及創(chuàng)建用戶角色的SQL(部分,詳細(xì)可到JdbcUserDetailsManager類查看):

public static final String DEF_CREATE_USER_SQL = "insert into users (username, password, enabled) values (?,?,?)";

public static final String DEF_INSERT_AUTHORITY_SQL = "insert into authorities (username, authority) values (?,?)";

public static final String DEF_USER_EXISTS_SQL = "select username from users where username = ?";

那么,如果要自定義數(shù)據(jù)庫表這需要配置如下,并且實(shí)現(xiàn)UserDetailsService接口:

auth.userDetailsService(userDetailsService());

@Bean
  public UserDetailsService userDetailsService() {
    return new CustomUserDetailsService();
  }

CustomUserDetailsService實(shí)現(xiàn)如下:

@Service
public class CustomUserDetailsService implements UserDetailsService {

  /** Logger */
  private static Logger log = LoggerFactory.getLogger(CustomUserDetailsService.class);

  @Resource
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    if (StringUtils.isBlank(username)) {
      throw new IllegalArgumentException("username can't be null!");
    }
    User user;
    try {
      user = userRepository.findByUserName(username);
    } catch (Exception e) {
      log.error("讀取用戶信息異常,", e);
      return null;
    }
    if (user == null) {
      return null;
    }
    List roles = userRepository.findRoles(user.getUserId());
    List authorities = new ArrayList<>();
    for (UserAuthority role : roles) {
      SimpleGrantedAuthority authority = new SimpleGrantedAuthority(String.valueOf(role.getAuthId()));
      authorities.add(authority);
    }
    return new org.springframework.security.core.userdetails.User(username, "1234", authorities);
  }


}

我們需要實(shí)現(xiàn)loadUserByUsername方法,這里面其實(shí)級做了兩件事:查詢用戶信息并返回該用戶的角色信息。

數(shù)據(jù)庫設(shè)計(jì)如下:

java中Spring Security的實(shí)例詳解

數(shù)據(jù)庫設(shè)計(jì)

g_users:用戶基本信息表
g_authority:角色信息表
r_auth_user:用戶角色信息表,這里沒有使用外鍵約束。

使用mybatis generator生成mapper后,創(chuàng)建數(shù)據(jù)源SecurityDataSource。

@Configuration
@ConfigurationProperties(prefix = "security.datasource")
@MapperScan(basePackages = DataSourceConstants.MAPPER_SECURITY_PACKAGE, sqlSessionFactoryRef = "securitySqlSessionFactory")
public class SecurityDataSourceConfig {

  private String url;

  private String username;

  private String password;

  private String driverClassName;

  @Bean(name = "securityDataSource")
  public DataSource securityDataSource() {
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    return dataSource;
  }

  @Bean(name = "securityTransactionManager")
  public DataSourceTransactionManager securityTransactionManager() {
    return new DataSourceTransactionManager(securityDataSource());
  }

  @Bean(name = "securitySqlSessionFactory")
  public SqlSessionFactory securitySqlSessionFactory(@Qualifier("securityDataSource") DataSource securityDataSource)
      throws Exception {
    final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(securityDataSource);
    sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
        .getResources(DataSourceConstants.MAPPER_SECURITY_LOCATION));
    return sessionFactory.getObject();
  }

  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getDriverClassName() {
    return driverClassName;
  }

  public void setDriverClassName(String driverClassName) {
    this.driverClassName = driverClassName;
  }
}

那么DAO UserRepository就很好實(shí)現(xiàn)了:

public interface UserRepository{

  User findByUserName(String username);

  List findRoles(int userId);

}

在數(shù)據(jù)庫插入相關(guān)數(shù)據(jù),重啟項(xiàng)目。仍然訪問首頁跳轉(zhuǎn)到登錄頁后輸入數(shù)據(jù)庫插入的用戶信息,如果成功跳轉(zhuǎn)到首頁這說明認(rèn)證成功。

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


分享題目:java中SpringSecurity的實(shí)例詳解
分享網(wǎng)址:http://weahome.cn/article/pdsdig.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部