上篇:springBoot使用springSecurity入门详细配置,自定义登录,RBAC权限模型,数据库(mybatis+mysql)验证登录,验证码,json格式交互等(上篇)
写了:
- springBoot项目使用security
- 配置介绍
- 自定义登录页面
- 自定义登陆成功失败处理器
- 添加验证码验证过滤
下篇开始
1.自定义用户认证的数据来源,内存以及数据库
前面我们一直使用security默认提供的user账号以及启动生产来登录,现在我们来配置自己用户信息;
security用户数据的配置在前面也已经介绍了,即配置类重写configure(AuthenticationManagerBuilder auth)方法
下面将介绍两种数据来源
-
直接配置在内存中
这种比较简单,直接在配置文件yml配置即可
这样我们就配置一个用户在我们的内存中,重新启动项目你会发现控制台不再打印一个加密的密码,也就是说只有我们没有配置自己用户数据来源时security才会给我们提供默认的用户user,一旦我们配置自己的用户数据将不再提供默认用户user; 成功!spring: security: user: name: admin password: admin
-
配置数据库来源
更多的时候我们的用户数据是放在数据库中,我们就需要配置数据库来源了,配置类重写configure(AuthenticationManagerBuilder auth)指定我们自定义数据来源;
数据库:我使用的是mysql
持久层框架:使用springJpa,之前一直使用的是mybatis,最近实习发现公司使用JPA比较多,所以这次顺便学学使用JPA
1.使用Jpa,并使用其自动创建表功能,准备好数据库数据
添加依赖
<!--druid数据库连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.35</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
在自己的mysql数据库建立一个security数据库
配置Jpa以及数据库连接池
用户Entity类,实现UserDetails接口spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver: com.mysql.jdbc.Driver druid: username: password: url: jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf-8&useSSL=false initial-size: 1 max-active: 5 min-idle: 1 jpa: show-sql: true #显示sql语句 hibernate: ddl-auto: update #自动建表 open-in-view: true properties: hibernate: enable_lazy_load_no_trans: true #将Jpa的session生命周期扩大
当我们启动项目使Jpa会自动会帮我们创建表,使用mybatis的,自己用下面sql创建表以及添加一条数据@Data @Entity @Table(name = "user", uniqueConstraints = {@UniqueConstraint(columnNames = {"username"}), @UniqueConstraint(columnNames = {"email"})}) public class User implements UserDetails { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer u_id; @Column(nullable = false) @Length(min = 3, max = 20) private String username; @Column(nullable = false,length = 100) @JsonIgnore private String password; @Column(nullable = false) @Length(min = 3, max = 20) private String realName; @Column(nullable = false, length = 50) private String email; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date registerDate; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date lastLogin; private boolean isEnabled=true; private boolean isAccountNonExpired=true; private boolean isAccountNonLocked=true; private boolean isCredentialsNonExpired=true; @ManyToMany @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "u_id"), inverseJoinColumns = @JoinColumn(name = "r_id")) private List<Role> roleList; // 存储用户的权限 @Transient private List<GrantedAuthority> authorities; @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof User)) return false; User user = (User) obj; boolean boo = this.username.equals(user.getUsername()); return boo; } @Override public int hashCode() { return username != null ? username.hashCode() : 0; } @Override public String toString() { return "User{" + "u_id=" + u_id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", realName='" + realName + '\'' + ", email='" + email + '\'' + ", registerDate=" + registerDate + ", lastLogin=" + lastLogin + ", isEnabled=" + isEnabled + ", isAccountNonExpired=" + isAccountNonExpired + ", isAccountNonLocked=" + isAccountNonLocked + ", isCredentialsNonExpired=" + isCredentialsNonExpired + ", roleList=" + roleList + ", authorities=" + authorities + '}'; } }
Jpa在测试类添加一个用户,mybatis使用上面添加一条用户的跳过这个SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `u_id` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `is_account_non_expired` bit(1) NOT NULL, `is_account_non_locked` bit(1) NOT NULL, `is_credentials_non_expired` bit(1) NOT NULL, `is_enabled` bit(1) NOT NULL, `last_login` datetime NULL DEFAULT NULL, `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `real_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `register_date` datetime NULL DEFAULT NULL, `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`u_id`) USING BTREE, UNIQUE INDEX `UKsb8bbouer5wak8vyiiy4pf2bx`(`username`) USING BTREE, UNIQUE INDEX `UKob8kqyqqgmefl0aco34akdtpe`(`email`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, '[email protected]', b'1', b'1', b'1', b'1', NULL, '$2a$10$RaDnhjsjVAoXE9DuOJxPV.BhJ0uX5oBtRJqvn6PSjQR7ASvZ53Z.a', 'admin', NULL, 'admin'); SET FOREIGN_KEY_CHECKS = 1;
运行项目成功,看自己的数据库@SpringBootTest public class SecurityApplicationTests { @Autowired UserRepository userRepository; // @Autowired // RoleRepository roleRepository; // @Autowired // PermissionRepository permissionRepository; @Test void contextLoads() { BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); User user = new User(); user.setUsername("admin"); user.setPassword(bCryptPasswordEncoder.encode("admin")); user.setEmail("[email protected]"); user.setRealName("admin"); // Permission adminPermission = new Permission(); // adminPermission.setPermName("管理员用户权限"); // adminPermission.setPermTag("ROLE_ADMIN"); // Permission commonPermission = new Permission(); // commonPermission.setPermName("普通用户权限"); // commonPermission.setPermTag("ROLE_COMMON"); // permissionRepository.save(adminPermission); // permissionRepository.save(commonPermission); // // List<Permission> permissions = new ArrayList<>(); // // permissions.add(commonPermission); // Role commonRole= new Role(); // commonRole.setRoleName("普通用户"); // commonRole.setRoleDesc("普通用户角色"); // commonRole.setPermissionList(permissions); // roleRepository.save(commonRole); // // permissions.add(adminPermission); // Role adminRole= new Role(); // adminRole.setRoleName("管理员用户"); // adminRole.setRoleDesc("管理员用户角色"); // adminRole.setPermissionList(permissions); // roleRepository.save(adminRole); // // List<Role> roles = new ArrayList<>(); // // roles.add(adminRole); // user.setRoleList(roles); userRepository.save(user); System.out.println(user); System.out.println(userRepository.findAll()); } }
数据库数据准备完毕
1.自定义数据来源,将数据库的用户提供给security,供其验证登陆
jpa接口
实现UserDetailsService接口实现UserDetails loadUserByUsername(String s)方法,security根据这个方法获取数据库用户数据public interface UserRepository extends JpaRepository<User,Integer> { User findByUsername(String username); }
将该实现类配置给security,在配置类重写void configure(AuthenticationManagerBuilder auth)//security自定义验证登陆用户时的数据来源,从数据库获取 @Component public class MyUserDetailService implements UserDetailsService { @Autowired UserRepository userRepository; /** * 根据用户名获取用户信息 * * @param s 用户名 * @return User 返回一个用户信息 * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { User user = userRepository.findByUsername(s); System.out.println(user); // if (user != null) { // List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); // for (Role role : user.getRoleList()) { // for (Permission p : role.getPermissionList()) { // GrantedAuthority authority = new SimpleGrantedAuthority(p.getPermTag()); // authorities.add(authority); // } // //将权限集合放进user // user.setAuthorities(authorities); // System.out.println("当前用户是: " + user.getUsername()); // } // } return user; } }
ok!启动项目 成功!!@Autowired private MyUserDetailService myUserDetailService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(myUserDetailService).passwordEncoder(passwordEncoder()); }
2.RBAC权限模型
可以看出前面所有用户都是一样的,这样的功能有点单调,如果我们希望用户是有所区别,就像windows用户组一样,我们希望不同的用户拥有不同的权限,因为我们网站不同模块有些对所有人开放,有些只对管理员开放,有些只对vip用户开放;这样就需要RBAC权限模型了
关于概念理念可以看看:
https://www.cnblogs.com/aoxueshou/p/10115359.html
我们就开始我们代码:三张基本表user、role、permission,以及阐述之间关系多对多的两张中间表,E-R图如下
1.JPA的Entity:
user:
//implements UserDetails
@Data
@Entity
@Table(name = "user",
uniqueConstraints = {@UniqueConstraint(columnNames = {"username"}), @UniqueConstraint(columnNames = {"email"})})
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer u_id;
@Column(nullable = false)
@Length(min = 3, max = 20)
private String username;
@Column(nullable = false,length = 100)
@JsonIgnore
private String password;
@Column(nullable = false)
@Length(min = 3, max = 20)
private String realName;
@Column(nullable = false, length = 50)
private String email;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date registerDate;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date lastLogin;
private boolean isEnabled=true;
private boolean isAccountNonExpired=true;
private boolean isAccountNonLocked=true;
private boolean isCredentialsNonExpired=true;
@ManyToMany
@JoinTable(name="user_role",joinColumns = @JoinColumn(name="u_id"),
inverseJoinColumns = @JoinColumn(name="r_id"))
List<Role> roleList;
@Transient
private List<GrantedAuthority> authorities;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof User)) return false;
User user = (User) obj;
boolean boo = this.username.equals(user.getUsername());
return boo;
}
@Override
public int hashCode() {
return username != null ? username.hashCode() : 0;
}
}
role:
@Data
@Entity
@Table(name = "role",uniqueConstraints = {@UniqueConstraint(columnNames = {"roleName"})})
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer r_id;
@Column(nullable = false)
@Length(max = 20)
private String roleName;
@Column(nullable = false)
@Length(max = 20)
private String roleDesc;
@ManyToMany
@JoinTable(name="role_permission",joinColumns = @JoinColumn(name="r_id"),
inverseJoinColumns = @JoinColumn(name="p_id"))
private List<Permission> permissionList;
public Role() {
}
}
permission:
@Data
@Entity
@Table(name = "permission",uniqueConstraints = {@UniqueConstraint(columnNames = {"permName"}),@UniqueConstraint(columnNames = {"permTag"})})
public class Permission implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer p_id;
@Column(nullable = false)
@Length(max = 20)
private String permName;
@Column(nullable = false)
@Length(max = 20)
private String permTag;
public Permission(){
}
}
启动项目,自动创建如ER图里面对应的表
2.将数据库之前插入的用户删了,然后把测试类的方法注释全部弄掉运行测试方法,插入一个RBAC模型下的一个用户
启动测试方法,插入一个admin用户,两个角色(管理员,普通用户),两个权限(管理员权限,普通权限),admin用户拥有管理员角色,管理员角色拥有管理员权限以及普通权限;
mybatis就需要自己根据下面sql弄了:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`u_id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`is_account_non_expired` bit(1) NOT NULL,
`is_account_non_locked` bit(1) NOT NULL,
`is_credentials_non_expired` bit(1) NOT NULL,
`is_enabled` bit(1) NOT NULL,
`last_login` datetime NULL DEFAULT NULL,
`password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`real_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`register_date` datetime NULL DEFAULT NULL,
`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`u_id`) USING BTREE,
UNIQUE INDEX `UKsb8bbouer5wak8vyiiy4pf2bx`(`username`) USING BTREE,
UNIQUE INDEX `UKob8kqyqqgmefl0aco34akdtpe`(`email`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (2, '[email protected]', b'1', b'1', b'1', b'1', NULL, '$2a$10$sm2TYwjob0JCIDrKUBpBvusSDeUbhjn/4dzjYpoKtyusBBlW1fnF2', 'admin', NULL, 'admin');
SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`r_id` int(11) NOT NULL AUTO_INCREMENT,
`role_desc` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`role_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`r_id`) USING BTREE,
UNIQUE INDEX `UKbgeqjb5opmijvwc14fbtaj4xx`(`role_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, '普通用户角色', '普通用户');
INSERT INTO `role` VALUES (2, '管理员用户角色', '管理员用户');
SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
`u_id` int(11) NOT NULL,
`r_id` int(11) NOT NULL,
INDEX `FKto8gqveqi41eyylx7a2tqlfip`(`r_id`) USING BTREE,
INDEX `FKhqbsm81qe5n0g3phrjs0kucos`(`u_id`) USING BTREE,
CONSTRAINT `FKhqbsm81qe5n0g3phrjs0kucos` FOREIGN KEY (`u_id`) REFERENCES `user` (`u_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `FKto8gqveqi41eyylx7a2tqlfip` FOREIGN KEY (`r_id`) REFERENCES `role` (`r_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES (2, 2);
SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for permission
-- ----------------------------
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
`p_id` int(11) NOT NULL AUTO_INCREMENT,
`perm_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`perm_tag` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`p_id`) USING BTREE,
UNIQUE INDEX `UKnojgqoyrg7x15s2qpu9x8tu5q`(`perm_name`) USING BTREE,
UNIQUE INDEX `UKqhboiosst3rok6m9scsef9f5x`(`perm_tag`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of permission
-- ----------------------------
INSERT INTO `permission` VALUES (1, '管理员用户权限', 'ROLE_ADMIN');
INSERT INTO `permission` VALUES (2, '普通用户权限', 'ROLE_COMMON');
SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role_permission
-- ----------------------------
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
`r_id` int(11) NOT NULL,
`p_id` int(11) NOT NULL,
INDEX `FK92po1qlba53d8v5iuh13uhbsh`(`p_id`) USING BTREE,
INDEX `FKgdhemjxik42hbj22wao654453`(`r_id`) USING BTREE,
CONSTRAINT `FKgdhemjxik42hbj22wao654453` FOREIGN KEY (`r_id`) REFERENCES `role` (`r_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `FK92po1qlba53d8v5iuh13uhbsh` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of role_permission
-- ----------------------------
INSERT INTO `role_permission` VALUES (1, 2);
INSERT INTO `role_permission` VALUES (2, 2);
INSERT INTO `role_permission` VALUES (2, 1);
SET FOREIGN_KEY_CHECKS = 1;
如此便成功使用了RBAC设计模型;
应用RBAC到security
要知道真正代表权限的是peimission的perm_tag字段,又用角色关联权限,用户又关联角色来实现赋权;
前面我们只有管理员用户并且拥有管理员角色,管理员角色又有普通用户权限和管理员权限,现在我们添加一个普通用户并赋予普通用户角色使其拥有普通权限;
测试类:
@Test
void contextLoads() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
User user = new User();
user.setUsername("common");
user.setPassword(bCryptPasswordEncoder.encode("common"));
user.setEmail("[email protected]");
user.setRealName("common");
List<Role> roles = new ArrayList<>();
Role role= new Role();
role.setR_id(1);
roles.add(role);
user.setRoleList(roles);
userRepository.save(user);
}
运行,然后成功;
现在我们有两个用户common、admin,分别绑定普通用户角色跟管理员角色,而普通用户角色绑定普通用户权限,管理员角色绑定普通用户权限以及管理员权限;
配置security配置类:void configure(HttpSecurity http)方法
@Override
protected void configure(HttpSecurity http) throws Exception {
//添加验证码过滤器
http.addFilterBefore(checkCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
http
.authorizeRequests()
.antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")//需要ROLE_ADMIN才能访问
.antMatchers("/common/**").hasAuthority("ROLE_COMMON")//需要ROLE_COMMON才能访问
.anyRequest().authenticated()
.and()
.formLogin()
.usernameParameter("username")//与登陆页面一致
.passwordParameter("password")//与登陆页面一致
.loginPage("/login.html")//自定义登陆页面
.permitAll()//设置为允许所有人访问
.loginProcessingUrl("/securityLogin")//登陆处理请求路径与action一致即可,不需要我们实现
.permitAll()//设置为允许所有人访问
.successHandler(myAuthenticationSuccessHandler)
.failureHandler(myAuthenticationFailureHandler)
.and()
.logout()//登出配置
.logoutUrl("/logout")//不需要我们实现,访问这个自动登出
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.and()
.httpBasic()
.disable()
.csrf()
.disable();
}
找到之前的MyUserDetailService类,将其中注释去掉;这步的目的就是将在登陆时,从数据库找到用户信息以及用户的权限组封装起来交给security去进行其他的认证操作;需要用户类User实现UserDetails接口并定义List<GrantedAuthority> authorities属性以及其get、set方法,security会根据这个属性判断该用户拥有什么权限
@Component
public class MyUserDetailService implements UserDetailsService {
@Autowired
UserRepository userRepository;
/**
* 根据用户名获取用户信息
*
* @param s 用户名
* @return User 返回一个用户信息
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findByUsername(s);
System.out.println(user);
if (user != null) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (Role role : user.getRoleList()) {
for (Permission p : role.getPermissionList()) {
GrantedAuthority authority = new SimpleGrantedAuthority(p.getPermTag());
authorities.add(authority);
}
//将权限集合放进user
user.setAuthorities(authorities);
System.out.println("当前用户是: " + user.getUsername());
}
}
return user;
}
}
提供一个controller类
@RestController
public class SecurityController {
@RequestMapping("/admin/hello")
public String adminHello() {
return "admin Hello World";
}
@RequestMapping("/common/hello")
public String commonHello() {
return "common Hello World";
}
}
ok,重启项目,使用common登陆
登陆成功!分别访问:
http://localhost:8080/security/common/hello //能访问
http://localhost:8080/security/admin/hello //无法访问,因为admin下需要ROLE_ADMIN权限才能访问
使用admin用户登陆访问看看:全部能访问
运用成功