Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring启动表单登录自定义用户详细信息服务授权不工作_Java_Spring Boot_Spring Security_Spring Security Rest - Fatal编程技术网

Java Spring启动表单登录自定义用户详细信息服务授权不工作

Java Spring启动表单登录自定义用户详细信息服务授权不工作,java,spring-boot,spring-security,spring-security-rest,Java,Spring Boot,Spring Security,Spring Security Rest,我是Spring Boot的初学者,很难做到这一点。我觉得SpringBoot的安全API一点也不直观,但我正在努力实现它 我将使用MySql和JPA从数据库中获取用户, 但最初只是为了确保安全脚手架工作,我只是从员工详细信息服务硬编码一个用户 在经历了很多麻烦之后,我成功地获得了基本的身份验证,但是授权不起作用。 我对问题进行了编辑,以反映基本问题: 我知道在人们将此标记为重复之前还有其他问题,我已经检查了所有这些问题,他们都给出了我认为已经在我的应用程序中运行的基本答案 最后 /主路径用于主

我是Spring Boot的初学者,很难做到这一点。我觉得SpringBoot的安全API一点也不直观,但我正在努力实现它

我将使用MySql和JPA从数据库中获取用户, 但最初只是为了确保安全脚手架工作,我只是从员工详细信息服务硬编码一个用户

在经历了很多麻烦之后,我成功地获得了基本的身份验证,但是授权不起作用。 我对问题进行了编辑,以反映基本问题:

我知道在人们将此标记为重复之前还有其他问题,我已经检查了所有这些问题,他们都给出了我认为已经在我的应用程序中运行的基本答案

最后 /主路径用于主方法, /妈妈路径是为角色妈妈

代码如下:

//AppSecurityConfig.java
package com.straightwalls.absencemanagement.config;

import com.straightwalls.absencemanagement.service.EmployeeDetailsService;
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.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.userdetails.UserDetailsService;

import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

   protected void configure(HttpSecurity http) throws Exception {
    //Disabled for development
    http.authorizeRequests()
            .antMatchers("/mama").hasRole("MAMA")
            .antMatchers("/home").hasAnyRole("ROLE_HEAD", "ROLE_MAMA")
            .and()
            .formLogin();
}

    @Bean
    /*
    * Returning no op password encoder for now,
    * as we are not encoding passwords as no registration
    * implemented for Prototype. We would need to add the users from a separate service. W
    *
    * */
    public PasswordEncoder getPasswordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

}



//EmployeeDetailsService
package com.straightwalls.absencemanagement.service;

import com.straightwalls.absencemanagement.model.Employee;
import com.straightwalls.absencemanagement.model.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Service
public class EmployeeDetailsService implements UserDetailsService {


    @Override
    
    public UserDetails loadUserByUsername(String username)
                         throws UsernameNotFoundException {
         
    if (!username.equals("Mama")){
        throw new UsernameNotFoundException(
            "You got the wrong Username, should be mama"
        );
    }

    Employee employee = new Employee();
    Role role = new Role();
    role.setName("HEAD");
    employee
        .setUsername(username)
        .setPassword("1234")
        .setRole(role);

    return new EmployeePrincipal(employee);
    }
}


    //EmployeePrincipal.java
    package com.straightwalls.absencemanagement.service;
    
    import com.straightwalls.absencemanagement.model.Employee;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.util.Arrays;
    import java.util.Collection;
    
    
    public class EmployeePrincipal implements UserDetails {

    private Employee employee;
    
    //Added another default Constructor, incase
    public EmployeePrincipal(){

    }

    public EmployeePrincipal(Employee employee){
        this.employee = employee;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_HEAD"));
        //return Arrays.asList(new SimpleGrantedAuthority("ROLE_" + employee.getRole().getName()));
    }

    @Override
    public String getPassword() {
        return employee.getPassword();
    }

    @Override
    public String getUsername() {
        return employee.getUsername();
    }

    /*
    * Methods below are the rubbish methods, we keep as true for now
    *
    * */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}



//Login.java
package com.straightwalls.absencemanagement.api;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginApi {

    @RequestMapping("/")
    public String index(){
        return "Straight Walls absence management!";
    }

    @RequestMapping("/home")
    public String home(){
        return "Welcome to Home!";
    }

    /**
    * This method can be deleted in the end
    *
    */
    @RequestMapping("/mama")
    public String roleTest(){
        return "This end point is only for Mama!";
    }

}

//Employee.java
package com.straightwalls.absencemanagement.model;

import org.hibernate.annotations.Fetch;

import javax.persistence.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

@Entity
public class Employee {

    @Id
    private long id;
    private String firstName;
    private String lastName;
    private String username;
    private String password;
    private String startDate;

    @ManyToOne
    @JoinColumn(name = "roleId", referencedColumnName = "id")
    private Role role;

    @ManyToOne
    @JoinColumn(name = "departmentId", referencedColumnName = "id")
    private Department department;

    public Employee(){

    }

    public long getId() {
        return id;
    }

    public Employee setId(long id) {
        this.id = id;
        return this;
    }

    public String getFirstName() {
        return firstName;
    }

    public Employee setFirstName(String firstName) {
        this.firstName = firstName;
        return this;
    }

    public String getLastName() {
        return lastName;
    }

    public Employee setLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

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

    public String getStartDate() {
        return startDate;
    }


    public Employee setStartDate(LocalDate startDate) {
      this.startDate =   
      startDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
      return this;
    }

    public Role getRole() {
        return role;
    }

    public Employee setRole(Role role) {
        this.role = role;
        return this;
    }

    public Department getDepartment() {
        return department;
    }

    public Employee setDepartment(Department department) {
        this.department = department;
        return this;
    }
}
//AppSecurityConfig.java
包com.streamwalls.absencemanagement.config;
导入com.streamwalls.absencemanagement.service.employeedetails服务;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
进口
org.springframework.security.config
.annotation.authentication.builders.AuthenticationManagerBuilder;
导入org.springframework.security.config.annotation.web.builders.HttpSecurity;
导入org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
进口
org.springframework.security.config
.annotation.web.configuration.WebSecurity配置适配器;
导入org.springframework.security.core.userdetails.userdetails服务;
导入org.springframework.security.crypto.password.NoOpPasswordEncoder;
导入org.springframework.security.crypto.password.PasswordEncoder;
@配置
@启用Web安全性
公共类AppSecurityConfig扩展了WebSecurity配置适配器{
@自动连线
私有用户详细信息服务用户详细信息服务;
@凌驾
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
auth.userDetailsService(userDetailsService);
}
受保护的无效配置(HttpSecurity http)引发异常{
//残疾人促进发展
http.authorizeRequests()
.antMatchers(“/mama”).hasRole(“mama”)
.antMatchers(“/home”).hasAnyRole(“角色头”、“角色妈妈”)
.及()
.formLogin();
}
@豆子
/*
*目前没有返回操作密码编码器,
*因为我们没有将密码编码为“无注册”
*为原型实现。我们需要从单独的服务添加用户。W
*
* */
公共密码编码器getPasswordEncoder(){
返回NoOpPasswordEncoder.getInstance();
}
}
//雇员就业服务
包com.slightwalls.absencemanagement.service;
导入com.streamwalls.absencemanagement.model.Employee;
导入com.slightwalls.absencemanagement.model.Role;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.security.core.userdetails.userdetails;
导入org.springframework.security.core.userdetails.userdetails服务;
导入org.springframework.security.core.userdetails.UsernameNotFoundException;
导入org.springframework.stereotype.Component;
导入org.springframework.stereotype.Service;
@服务
公共类EmployeeDetailsService实现UserDetailsService{
@凌驾
公共用户详细信息loadUserByUsername(字符串用户名)
抛出UsernameNotFoundException{
如果(!username.equals(“Mama”)){
抛出新UsernameNotFoundException(
“你的用户名错了,应该是妈妈”
);
}
员工=新员工();
角色=新角色();
角色。设置名称(“头”);
雇员
.setUsername(用户名)
.setPassword(“1234”)
.setRole(role);
返回新员工主(员工);
}
}
//EmployeePrincipal.java
包com.slightwalls.absencemanagement.service;
导入com.streamwalls.absencemanagement.model.Employee;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.SimpleGrantedAuthority;
导入org.springframework.security.core.userdetails.userdetails;
导入java.util.array;
导入java.util.Collection;
公共类EmployeePrincipal实现UserDetails{
私人雇员;
//添加了另一个默认构造函数,以防万一
公共雇员原则(){
}
公共雇员负责人(雇员){
this.employee=employee;
}
@凌驾

public Collection通过清理代码并对grantedAuthories方法进行一些更改来解决这个问题,GrantedAuthories方法不需要这个角色_

还通过取消角色更改了hasRole、hasAnyRole和hasAnyAuthority_ 不知道为什么,但它现在起作用了

此外,API现在更容易理解

以下是更新的代码:

@Configuration
@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService);

        /*auth.inMemoryAuthentication()
                .withUser("appuser").password("1234").roles("HEAD")
                .and()
                .withUser("Mama").password("Mama").roles("MAMA");*/

    }

    @Override
    /*
    * Now we have learnt the basics of Spring Security & Authrization method is completed.
    * Lets fix Authentication first!
    * Got it to work with hasAuthority & hasAnyAuthority but not with roles, not sure why, but it works atm
    *
    * */
    protected void configure(HttpSecurity http) throws Exception {
        //Disabled for development
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/mama").hasAuthority("MAMA")
                .antMatchers("/home").hasAnyAuthority("HEAD", "MAMA")
                .anyRequest().authenticated()

                .and()
                .formLogin()
                    .loginPage("/")
                    .defaultSuccessUrl("/home");
    }

    @Bean
    /*
    * Returning no op password encoder for now, as we are not encoding passwords as no registration
    * implemented for Prototype. We would need to add the users from a separate service. W
    *
    * */
    public PasswordEncoder getPasswordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

}


//EmployeeDetailsService.java
@Service
public class EmployeeDetailsService implements UserDetailsService {


    @Override
    /*
    * First, we are testing the Employee details service, independent of the Database, just to make sure we have this part working,
    * For the purpose of these prototypes, we wont use password encoder because we are not registering,
    *
    * */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if (!username.equals("Mama")){
            throw new UsernameNotFoundException("You got the wrong Username, should be mama");
        }

        Employee employee = new Employee();
        Role role = new Role();
        role.setName("HEAD");
        employee
                .setUsername(username)
                .setPassword("1234")
                .setRole(role);

        return new EmployeePrincipal(employee);

    }
}


    //EmployeePrincipal.java
    public class EmployeePrincipal implements UserDetails {
    
        private Employee employee;
    
    
        public EmployeePrincipal(Employee employee){
            this.employee = employee;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
            authorities.add(new SimpleGrantedAuthority(employee.getRole().getName()));
            return  authorities;
        }
    
        @Override
        public String getPassword() {
            return employee.getPassword();
        }
    
        @Override
        public String getUsername() {
            return employee.getUsername();
        }
    
        /*
        * Methods below are the rubbish methods, we keep as true for now
        *
        * */
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    }


@RestController
public class LoginApi {

    @RequestMapping("/")
    public String index(){
        return "Index"
    }

    @RequestMapping("/home")
    public String home(){
        return "Home!";
    }

    /*
    * This method can be deleted in the end
    * */
    @RequestMapping("/mama")
    public String roleTest(){
        return "This end point is only for Mama!";
    }

}
@配置
@启用Web安全性
公共类AppSecurityConfig扩展了WebSecurity配置适配器{
@自动连线
用户详细信息服务用户详细信息服务;
@凌驾
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
auth.userDetailsService(userDetailsService);
/*auth.inMemoryAuthentication()
.withUser(“appuser”)。密码(“1234”)。角色(“头”)
.及()
.withUser(“Mama”)。密码(“Mama”)。角色(“Mama”)*/
}
@凌驾
/*
*现在,我们已经学习了Spring安全性的基础知识&身份验证方法已经完成。
*让我们先修复身份验证!
*让它与hasAuthority一起工作&hasAnyAuthority但不与角色一起工作,不确定为什么,但它可以工作
*
* */
受保护的无效配置(HttpSecurity http)引发异常