前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于springboot+mybatisplus构建系统管理平台(一)

基于springboot+mybatisplus构建系统管理平台(一)

作者头像
sucl
发布2019-08-07 11:58:27
2.1K0
发布2019-08-07 11:58:27
举报
文章被收录于专栏:企业平台构建企业平台构建

此次用到的技术当然以spring为核心,orm选择目前国产开源框架mybatisplus,由于没有对该框架有非常深度的认识,具体怎么样目前不做评论,安全框架使用springsecurity,由于之前对该框架一直没有了解太多,借此机会看是否可能更深度的理解其工作原理与设计理念,前端准备尝试使用vue,还是一样,没怎么用过,但是总要尝试一下。由于涉及到的技术点相对比较生疏,因此此次过程会相对艰辛与困难,但是,拭目以待!

首先在springboot中使用springsecurity比较简单,引入对应的依赖jar

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

其实就可以使用了,只不过这个时候我们在发送请求时,会统一被拦截打开一个飙到,需要输入用户名,密码才能继续下面的操作,而默认的用户为user,密码在系统启动时控制台中

当然,我们真正去使用时,不可能用这些默认配置,一般都会根据自己的业务需要添加一些认证逻辑与权限控制相关的逻辑。

那么扩展从使用角度来不复杂,但是如果去理解其原理或者配置比较复杂的权限模型,很不容易。首先我们需要自定义认证配置类,比如:

代码语言:javascript
复制
@NoArgsConstructor
@Configuration
@EnableWebSecurity
@EnableConfigurationProperties(WebSecurityProperties.class)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {}

关键点,添加@EnableWebSecurity,继承WebSecurityConfigurerAdapter。

基本所有的业务都是在该类中进行扩展,维护,当然默认的配置已经帮助我们实现了基础功能,我只用根据需要重写对应的方法,这里说几个关键方法:

代码语言:javascript
复制
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
}

该方法主要传入对象auth,主要涉及到用户认证的逻辑,比如构建用户认证实体,和shiro一样,在shiro中是通过Subject,而这里则是UserDetails,那么我们可以怎么配置:

代码语言:javascript
复制
*  1、基于内存 auth.inMemoryAuthentication().withUser("user").password("password");
*  2、基于指定数据源 auth.jdbcAuthentication().usersByUsernameQuery("select username,password,enabled from users where username = ?");
*  3、基于名录库 auth.ldapAuthentication()...
*  4、基于 UserDetailsService服务,需要自己实现该接口
*  5、基于 AuthenticationProvider,默认情况下authentication = UsernamePasswordAuthenticationToken,这个可以在我们的UserDetailsService中定义,
*  AuthenticationProvider有多种实现

站在开发者角度,我们一般通过两种方式进行用户认证,其实原理都是通过AuthenticationProvider实现,只不过我们开发的时候关注点在哪:

1、通过构建内置的UserDetailsAwareConfigurer,进而获取UserDetailsService,最后来构建UserDetails

2、或者通过配置AuthenticationProvider实现多类型用户登录

最简单的实现方式,由于我们一般系统用户体系都依赖于数据库,可以这样配置

代码语言:javascript
复制
auth.userDetailsService(userDetailsService)

其中userDetailsService也只用去实现UserDetailsService接口,在该接口中,我们能够拿到页面中输入的用户名,这里只需要根据用户名查询出用户,并构建UserDetails返回即可

代码语言:javascript
复制
@Service
public class DefaultUserDetailesService implements UserDetailsService {
    @Autowired
    private UserHolderService userHolderService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userHolderService.getUser(username);
        if(user==null) return null;
        return new User(user.getUsername(),user.getPassword(),null);
    }
}

然后看下第二个需要重写的,我们知道,在mvc中对static、publc、resources等资源可以直接访问,但是假如security后,会被拦截,所以需要单独处理下。

代码语言:javascript
复制
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/static/**").antMatchers("/favicon.ico")
            .mvcMatchers("/webjars/**");
}

最后一个,也是比较复杂的,下面有一段简单的配置

代码语言:javascript
复制
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
    .antMatchers("/login").permitAll()
    .anyRequest().authenticated()
    .and().formLogin().loginPage("/login").defaultSuccessUrl("/index").loginProcessingUrl("/login")
    .and().logout().permitAll()
    .and().csrf().disable();
}

其中有几点需要注意的是,我们设置了登录界面的请求为/login,由于spring默认的登录请求也是这个,可以在DefaultLoginPageGeneratingFilter中看到,那么会出现什么问题呢,在最开始使用该框架时,我们不用任何配置,访问接口时会自动进入一个需要输入用户名、密码的界面,就是因为请求默认进入这个拦截器中了,如果我们将自己的请求页面也这样配置,那么将不会进入我们自己的页面,所以可以将我们的登录请求该一下。当然,如果你坚持也要用/login,那么需要做些处理了。

在WebSecurityConfigurerAdapter构造器中,我们可以看到有一个参数disableDefaults,默认情况为false,那么就会加载一些系统默认的配置,我们可以将其改为true,那么DefaultLoginPageGeneratingFilter将不再生效,也就可以进入我们自己的页面中进行登录了。当然,这样又会出现另一个问题,An Authentication object was not found in the SecurityContext 要知道我们去掉了默认的配置,是否弄清了默认有哪些配置,如果把一些必要的元素取消了,那是否需要有对应的配置去代替?如果不知道,则还是保持原样把。

还有一个配置loginProcessingUrl,这个是什么意思?其实是在我们进行form提交时的action,必须要与我们配置的一致,并且为POST类型请求,否则,你提交请求时怎么进行用户认证?当然你不配置也行,因为默认使用的是loginPage属性。如果想深入了解,可以看UsernamePasswordAuthenticationFilter

代码语言:javascript
复制
public UsernamePasswordAuthenticationFilter() {
   super(new AntPathRequestMatcher("/login", "POST"));
}

还有几点需要说明的是,正常form表单提交,如果认证成功,会自动跳转到我们配置的成功页面,但是有时候我们使用的是ajax提交,可能就不能用默认的处理方式了,这个时候不放配置一下

代码语言:javascript
复制
http.formLogin().successHandler(new AuthenticationSuccessHandler() {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

    }
});

如果我们不配置,默认也会使用一个,SavedRequestAwareAuthenticationSuccessHandler。

其实spring security本身是一个功能强大内容繁琐的框架,当然如果站在使用者的角度其实没那么复杂,但是如果想了解其完整的技术实现细节可能不是三言两语可以概括,所以目前也不再过多深入。

下面说下mybatis-plus,用过mybatis的都知道,mybatis作为一个相对简单的半ORM框架,因为只实现了数据->实体的映射,其主要为我们封装了jdbc的一些基础功能,比如连接的创建、事务的管理、返回值的封装等等,但是具体如何实现jdbc的功能,其实都是需要我们自己去实现的,最终将这块模块统一为xml包装的sql,所以说其灵活在与由开发者自己去完成想要的功能了。而mybatis-plus,没有对原框架做任何的修改,只不过在其基础上 进行了一定的扩展,就之前使用的情况来看,主要有以下几个方面:

1、构建了统一的mapper实现,实现了单表的增删改查

2、定义了基础的service,供开发者使用

3、添加 了id生存策略

4、添加了分页和一些其它的拦截器

5、增加了lambda表达式,快速构建CRUD操作条件

6、添加了代码生成模板,快速通过表生成完整的代码

由于之前使用的不是太深入,所有也有很多功能没有用到,只是做了简单的罗列,而我们使用起来其实也没那么复杂,首先需要引入相关的依赖jar:

代码语言:javascript
复制
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatisplus.version}</version>
</dependency>

其次在配置文件中根据自己的情况加入下面的配置:

代码语言:javascript
复制
mybatis-plus.mapper-locations=classpath*:com/sucl/smsm/*/mapper/**Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
mybatis-plus.type-aliases-package=com.sucl.smsm.*.entity
mybatis-plus.global-config.refresh=true
mybatis-plus.global-config.db-config.db-type: mysql
#      id-type: uuid
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false

之后就是一些entity、mapper、service、web的写法了

代码语言:javascript
复制
@Data
@EqualsAndHashCode(callSuper = true)
//@Accessors(chain = true)
public class User extends BaseEntity implements IUser {

    private static final long serialVersionUID = 1L;

    @TableId(value = "USER_ID", type = IdType.UUID)
    private String userId;

    @TableField("USER_NAME")
    private String username;
}
代码语言:javascript
复制
public interface UserMapper extends BaseMapper<User> {

}
代码语言:javascript
复制
public interface UserService extends IService<User> {

}
代码语言:javascript
复制
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{

}
代码语言:javascript
复制
@RestController
@RequestMapping("/sys/user")
public class UserController extends BaseController<UserService,User> {

}

可以看到,我们没有定义任何的方法,但是却有了基本的功能能够 完成单表几乎任何的操作,这主要归根与BaseMapper、IService、ServiceImpl这些写内置的接口与实现。

因此对于后台的开发相对比较简单了。

当然这只是完成了其中一部分,说好的vue还没用到,上面说的这些究竟如何实现,这些会在之后进行完善,毕竟篇幅较大,不利于阅读。

代码:https://github.com/suspring/springboot-mybatisplus-security-ms.git

代码持续更新中...

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档