Spring Security 簡單瞭解與配置
阿新 • • 發佈:2020-09-08
首先匯入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.37</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
在controller寫幾個測試介面
package com.yaimer.d; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @program: SpringSecurityTestProject * @description: * @author: yaimer * @create: 2020-09-05 01:04 **/ @Controller public class inedx { @GetMapping("/log") @ResponseBody public String getHello(){ return "hello_阪井泉水"; } @GetMapping("/admin/log") @ResponseBody public String getAdminLog(){ return "hello_阪井泉水_admin_zard"; } @GetMapping("/user/log") @ResponseBodypublic String getUserLog(){ return "hello_阪井泉水_user_zard"; } }
配置security 主要是自己寫一個@Configuration 配置登入頁,設定角色等資訊,也可在配置檔案properties或者yml中設定登入角色,會被Configuration中覆蓋
server.port=8081 #spring security user spring.security.user.name=yaimer spring.security.user.password=admin spring.security.user.roles=admin #spring security connection spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql:///bytest?useUnicode=true&characterEncoding=utf-8 #rabbitmq
package com.yaimer.d; import ch.qos.logback.core.net.ObjectWriter; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl; 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.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.JdbcUserDetailsManager; import javax.sql.DataSource; import java.io.PrintWriter; /** * @program: SpringSecurityTestProject * @description: 第二種security * @author: yaimer * @create: 2020-09-05 01:31 **/ @Configuration public class securityConfig extends WebSecurityConfigurerAdapter { /* * 加密 * */ @Bean PasswordEncoder passwordEncoder(){ return NoOpPasswordEncoder.getInstance(); } /* * 設定角色,會覆蓋properties * */ /*@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("zard") .password("admin") .roles("admin") .and() .withUser("pzy") .password("123") .roles("user") ; }*/ /** * 設定角色 * @return */ @Autowired DataSource dataSource; @Override @Bean protected UserDetailsService userDetailsService() { //每次執行建立使用者 /*InMemoryUserDetailsManager manager= new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("zard").password("admin").roles("admin").build()); manager.createUser(User.withUsername("pzy").password("123").roles("user").build());*/ //idea 快捷鍵alt+ins 搜尋 users.dll 複製語句建表 JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource); if (!manager.userExists("zard")){ manager.createUser(User.withUsername("zard").password("admin").roles("admin").build()); } if (!manager.userExists("pzy")){ manager.createUser(User.withUsername("pzy").password("123").roles("user").build()); } return manager; } /** * 繼承角色許可權 * @param http * @throws Exception */ @Bean RoleHierarchy roleHierarchy(){ RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl(); roleHierarchy.setHierarchy("ROLE_admin > ROLE_user"); return roleHierarchy; } /*配置登入頁*/ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("admin") .antMatchers("/user/**").hasRole("user") .anyRequest().authenticated() .and() .formLogin() .loginPage("/Login.html") .loginProcessingUrl("/dol") /* .usernameParameter("name") .passwordParameter("pass")*/ .successHandler((request, response, authentication) -> { response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString(authentication.getPrincipal())); System.out.println(new ObjectMapper().writeValueAsString(authentication.getPrincipal())); out.flush(); out.close(); }) .failureHandler((request, response, exception) -> { response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString(exception.getMessage())); System.out.println(new ObjectMapper().writeValueAsString(exception.getMessage())); out.flush(); out.close(); }) /*.defaultSuccessUrl("/log",true)*/ .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessHandler((request, response, authentication) -> { response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString("登出成功")); out.flush(); out.close(); }) .permitAll() .and() .csrf().disable() .exceptionHandling() .authenticationEntryPoint((request, response, authException) -> { response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString("沒有登入喲")); out.flush(); out.close(); }) ; } /*過濾靜態資源*/ @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/js/**","/css/**","/img/**"); } }
然後就可以執行主程式,在位址列輸入頁面,需要登陸後訪問
登陸zard可以訪問/admin和/user下面的請求,登陸pzy則只能訪問/user下面的請求,logout可退出登陸