知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>netkiller.cn</groupId> <artifactId>api.netkiller.cn</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>api.netkiller.cn</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-oracle</artifactId> <version>1.0.0.RELEASE</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <!-- <version>12.1.0.1</version> --> <version>11.2.0.3</version> <scope>system</scope> <systemPath>${basedir}/lib/ojdbc6.jar</systemPath> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-velocity</artifactId> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source /> <target /> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <warSourceDirectory>WebContent</warSourceDirectory> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project>
src/main/resources/application.properties
添加預設用戶,角色user,用戶名neo,密碼password
security.user.name=neo security.user.password=password security.user.role=USER
現在啟動Application,然後嘗試訪問url,這時會彈出對話框,提示用戶用戶輸入用戶名與密碼。使用上面的密碼便可登陸。
package api; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @SpringBootApplication @EnableAutoConfiguration @ComponentScan({ "api.config", "api.web", "api.rest", "api.service" }) @EnableMongoRepositories @EnableJpaRepositories public class Application { public @Bean WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } }; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
注意WebSecurityConfigurer必須在 ComponentScan 的掃瞄範圍
package api.config; 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.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication(). withUser("user1").password("secret1").roles("USER") .and(). withUser("user2").password("secret2").roles("USER") .and(). withUser("admin").password("secret").roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().fullyAuthenticated(); http.httpBasic(); http.csrf().disable(); } }
@RestController @RequestMapping("/service") public class UserService { @RequestMapping(value = "/echo/{in}", method = RequestMethod.GET) public String echo(@PathVariable(value = "in") final String in, @AuthenticationPrincipal final UserDetails user) { return "Hello " + user.getUsername() + ", you said: " + in; } }
curl -u user:password http://172.16.0.20:8080/index.html curl http://user:password@172.16.0.20:8080/index.html
MongoDB 為 Security 用戶認證提供數據存儲。
package mis.domain; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.Indexed; public class Administrator { @Id private String id; @Indexed(unique = true) private String username; private String password; private String authority; public Administrator() { // TODO Auto-generated constructor stub } public Administrator(String username, String password) { this.username = username; this.password = password; } public String getId() { return id; } public void setId(String id) { this.id = id; } 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 getAuthority() { return authority; } public void setAuthority(String authority) { this.authority = authority; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + ", authority=" + authority + "]"; } }
package mis.repository; import org.springframework.data.mongodb.repository.MongoRepository; import mis.domain.Administrator; public interface AdministratorRepository extends MongoRepository<Administrator, String> { public Administrator findByUsername(String username); }
package mis.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; 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.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import mis.domain.Administrator; import mis.repository.AdministratorRepository; @Configuration class GlobalAuthenticationConfigurer extends GlobalAuthenticationConfigurerAdapter { @Autowired AdministratorRepository administratorRepository; @Override public void init(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()); } @Bean UserDetailsService userDetailsService() { return new UserDetailsService() { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Administrator administrator = administratorRepository.findByUsername(username); if (administrator != null) { return new User(administrator.getUsername(), administrator.getPassword(), AuthorityUtils.createAuthorityList(administrator.getAuthority())); } else { throw new UsernameNotFoundException("could not find the administrator '" + username + "'"); } } }; } } @Configuration @EnableWebSecurity public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { public WebSecurityConfigurer() { // TODO Auto-generated constructor stub } @Override protected void configure(HttpSecurity http) throws Exception { // http.authorizeRequests().anyRequest().fullyAuthenticated().and().httpBasic().and().csrf().disable(); // http.authorizeRequests().antMatchers("/", "/index.html", "/css/**", // "/js/**","/static/**","/setup.html").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login.html").permitAll().and().logout().permitAll().and().httpBasic(); // http.authorizeRequests().antMatchers("/**" // ).permitAll().and().httpBasic(); http.authorizeRequests().antMatchers("/ping", "/v1/*/ping", "/v1/public/**").permitAll().anyRequest().authenticated().and().rememberMe().and().httpBasic().and().csrf().disable(); } }