使用Spring Boot Security Starter加密REST服务

 

Spring Initializr http://start.spring.io/ 是引导Spring Boot项目的绝佳工具。 我们使用它创建我们的案例:

  • 启动Spring Initializr并选择以下内容
    • 选择 com.samples.springboot 为组
    • 选择 student-services 为神器
    • 选择以下依赖项
      • 卷筒纸
  • 单击“生成项目”。
  • 将项目导入Eclipse。
  • 如果您想了解属于该项目的所有文件,可以访问此处。

设置简单的Web应用程序

让我们快速设置一个简单的Web应用程序,以确保使用Spring Security。 我们将创建一个Controller,它将重定向到欢迎视图 - 一个简单的jsp。

JSP支持

我们希望使用JSP作为视图。 Spring Boot Starter Web的默认嵌入式servlet容器是tomcat。 要启用对JSP的支持,我们需要在tomcat-embed-jasper上添加依赖项。

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

添加登录控制器

LoginController将根URL“/”映射到showLoginPage方法。 硬编码名称将填充到模型中。 它返回一个映射到welcome.jsp的视图名称“welcome”。

package com.samples.springboot.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class LoginController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String showLoginPage(ModelMap model) {
        model.put("name", "samples");
        return "welcome";
    }

}

添加welcome.jsp

welcome.jsp是一个简单的jsp,带有欢迎消息。

<div class="container">
    Welcome ${name}!! 
</div>

配置视图解析器

欢迎jsp在文件夹src / main / webapp / WEB-INF / jsp /中。 我们将在application.properties中配置一个视图解析器,以将视图名称映射到物理jsp

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

运行Web应用程序

将StudentServicesApplication作为java应用程序启动。 以下屏幕截图显示了在http:// localhost:8080上启动的应用程序。

 

添加简单REST服务

让我们也添加一个简单的REST服务。 我们将补充

  • 两个模型对象 - 课程和学生。 学生可以注册多门课程。
  • 一个业务服务 - 管理业务逻辑。 我们使用的大多数业务逻辑都位于存储在静态ArrayList中的硬编码数据之上。
  • 一个休息控制器 - StudentController。 公开一个休息服务以检索学生注册的课程列表。

模型和业务逻辑

下面的代码段显示了模型对象Course和Student的摘录。

public class Course {
	private String id;
	private String name;
	private String description;
	private List<String> steps;
}
public class Student {
	private String id;
	private String name;
	private String description;
	private List<Course> courses;
}

StudentService提供了一种 public List<Course> retrieveCourses(String studentId) 检索学生注册课程 的方法

@Component
public class StudentService {

	private static List<Student> students = new ArrayList<>();

	static {
		// Initialize Data
		Course course1 = new Course("Course1", "Spring", "10 Steps",
				Arrays.asList("Learn Maven", "Import Project", "First Example",
						"Second Example"));
		Course course2 = new Course("Course2", "Spring MVC", "10 Examples",
				Arrays.asList("Learn Maven", "Import Project", "First Example",
						"Second Example"));

		Student ranga = new Student("Student1", "Ranga Karanam",
				"Hiker, Programmer and Architect", new ArrayList<>(
						Arrays.asList(course1, course2)));

		students.add(ranga);
	}

	public Student retrieveStudent(String studentId) {
		for (Student student : students) {
			if (student.getId().equals(studentId)) {
				return student;
			}
		}
		return null;
	}

	public List<Course> retrieveCourses(String studentId) {
		Student student = retrieveStudent(studentId);

		if (student == null) {
			return null;
		}

		return student.getCourses();
	}
}

创建REST服务

Rest Service StudentController 在URI映射“/ students / {studentId} / courses”中公开了一个简单的Get服务。 StudentService 是自动连接的。

package com.samples.springboot.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.samples.springboot.model.Course;
import com.samples.springboot.service.StudentService;

@RestController
public class StudentController {

	@Autowired
	private StudentService studentService;

	@GetMapping("/students/{studentId}/courses")
	public List<Course> retrieveCoursesForStudent(@PathVariable String studentId) {
		return studentService.retrieveCourses(studentId);
	}
}

执行REST服务

执行休息服务很容易。 在您的浏览器或您最喜爱的休息客户端中访问URL http:// localhost:8080 / students / Student1 / courses。

 

添加Spring Boot Starter Security

现在让我们将Spring Boot Starter Security添加为该项目的依赖项。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

 

自动配置

当我们重新启动应用程序时,我们会在日志中看到以下语句。

Mapping filter: 'springSecurityFilterChain' to: [/*]

Using default security password: 25e07e82-720d-4109-ba8d-25177c6347e6

Creating filter chain:
...
...

所有这些魔力都是因为自动配置:

  • Mapping filter: 'springSecurityFilterChain' to: [/*] :默认情况下,为应用程序中的所有URL启用Spring Security。
  • 基本身份验证是默认设置。
  • Using default security password: 25e07e82-720d-4109-ba8d-25177c6347e6 :默认用户标识是用户。 默认密码打印在服务器启动日志中。 在此示例中,密码为25e07e82-720d-4109-ba8d-25177c6347e6
  • 某些过滤器链配置为启用安全性

执行REST服务

当我们现在在http:// localhost:8080 / students / Student1 / courses执行Rest Service时,它会返回身份验证失败。 状态为401,消息“Bad credentials”。 这是因为我们的服务现在受到Spring Security的保护。

{
  "timestamp": 1485768623632,
  "status": 401,
  "error": "Unauthorized",
  "message": "Bad credentials",
  "path": "/students/Student1/courses"
}

 

使用基本身份验证执行Rest服务

通过搜索从日志中获取密码 Using default security password: 用户标识是用户。 使用此组合可使用基本身份验证执行服务。

 

运行Web应用程序

当您在浏览器中启动URL http:// localhost:8080时,会弹出一个要求输入用户名和密码的弹出窗口。 您需要输入我们为REST服务提供的相同详细信息。

通过添加一个简单的依赖Spring Boot Starter Security,我们开启了很多魔术。

配置自定义用户和角色

我们现在配置自定义用户和角色

  • 我们将使用Admin和User两个角色。 管理员角色可以访问Web应用程序,用户角色可以访问执行REST服务。
  • 我们将使用凭据admin1 / secret1为Admin角色创建一个用户
  • 我们将使用凭据user1 / secret1为User角色创建一个用户
package com.samples.springboot.security;


@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	// Authentication : User --> Roles
	protected void configure(AuthenticationManagerBuilder auth)
			throws Exception {
		auth.inMemoryAuthentication().passwordEncoder(or
g.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance()).
withUser("user1")
.password("secret1")
				.roles("USER").and().withUser("admin1").password("secret1")
				.roles("USER", "ADMIN");
	}

	// Authorization : Role -> Access
	protected void configure(HttpSecurity http) throws Exception {
		http.httpBasic().and().authorizeRequests().antMatchers("/students/**")
				.hasRole("USER").antMatchers("/**").hasRole("ADMIN").and()
				.csrf().disable().headers().frameOptions().disable();
	}

}

执行REST服务

现在我们可以使用user1 / secret1组合来执行休息服务。

启动Web应用程序

我们需要在弹出窗口中使用admin1 / secret1组合来启动Web应用程序。

Spring Boot