当前位置: 首页 > 科技观察

SpringSecurity系列之CAS单点登录对接数据库

时间:2023-03-14 22:39:54 科技观察

1。总体思路我们先来看一下总体思路。我们使用CASServer进行单点登录,CASServer主要负责认证,也就是主要解决登录问题。登录成功后,还有一个权限处理的问题,由各个CASClient自行处理,并没有在CASServer中完成。上一篇宋哥教大家定义UserDetailsS??ervice。不知道大家还记不记得下面这段代码(忘了参考上一篇文章:SpringBoot实现单点登录的第三种方案!):s,"123",true,true,true,true,AuthorityUtils.createAuthorityList("ROLE_user"));}}这段代码是什么时候执行的?如果我们不使用CAS集合,那么这段代码当然是在用户登录的时候执行的,当用户登录的时候,会从数据库中查询用户的信息,然后进行验证(参考本系列上一篇文章了解)).如果我们使用CAS集,用户登录的验证会在CASServer上进行,CASClient不需要做验证工作,但是为什么要定义UserDetailsS??ervice呢?这是为了当用户在CASServer上登录成功后,将用户名返回给CASClient,然后我们根据用户名去数据库中获取用户的详细信息,包括用户的角色,等等,然后在后续的认证中使用该角色。嗯,这是我们的总体思路。接下来我们看一下具体的实现。2、具体实现下面的配置是在松哥教你入门SpringBoot+CAS单点登录一文的基础上完成的,所以没有看过上一篇文章的朋友建议先看一下。2.1准备工作首先我们在数据库中准备用户表、角色表和用户角色关联表:255)COLLATEutf8mb4_unicode_ciDEFAULTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_unicode_ci;CREATETABLE`t_user`(`id`bigint(20)NOTNULLAUTO_INCREMENT,`account_non_expired`位(1)`NOTNULL,`account_TLL(non1),`credentials_non_expired`位(1)NOTNULL,`enabled`位(1)NOTNULL,`password`varchar(255)COLLATEutf8mb4_unicode_ciDEFAULTNULL,`username`varchar(255)COLLATEutf8mb4_unicode_ciDEFAULTNULL,PRIMARYKEY(`id`))ENGINET=InnoARD4utf8mb4_ciDEFAULTNULL;`t_user_roles`(`t_user_id`bigint(20)NOTNULL,`roles_id`bigint(20)NOTNULL,KEY`FKj47yp3hhtsoajht9793tbdrp4`(`roles_id`),KEY`FK7l00c7jb4804xlpmk1k26texy`(`t_user_id`),CONSTRAINT`FK7l00c7jb4804xlpmk1k26texy`FOREIGNKEY(`t_user_id`)参考`t_user`(`id`),CONSTRAINT`FKj47yp3hhtsoajht9793tbdrp4`FOREIGNKEY(`roles_id`)REFERENCES`t_role`(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_unicode_ci;INSERTINTO`t_role`(`id`,`name`,`name_zh`)VALUES(1,'ROLE_admin','管理员'),(2,'ROLE_user','普通用户');INSERTINTO`t_user`(`id`,`account_non_expired`,`account_non_locked`,`credentials_non_expired`,`enabled`,`password`,`username`)VALUES(1,b'1',b'1',b'1',b'1','123','javaboy'),(2,b'1',b'1',b'1',b'1','123','南方小雨长江');INSERTINTO`t_user_roles`(`t_user_id`,`roles_id`)VALUES(1,1),(2,2);2.2CASServer那么我们需要在CASServer的pom.xml文件中添加两个依赖:org.apereo.cascas-server-support-jdbc-drivers${cas.version}<依赖关系>org.apereo.cascas-server-support-jdbc${cas.version}注意这里不需要添加数据库驱动,系统会自动解决添加后在src/main/resources/application.properties文件中添加如下配置:cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/withjpa?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=falsecas.authn.jdbc.query[0].user=rootcas.authn.jdbc.query[0].password=123cas.authn.jdbc.query[0].sql=select*fromt_userwhere用户名=?cas.authn.jdbc.query[0].fieldPassword=passwordcas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver配置前三行是数据库的基本连接配置,这就不需要我多说了。第四行配置用户查询sql,根据用户名查询该用户的所有信息。第五行表示密码在数据库中的字段名是什么。第六行是数据库驱动。OK,配置完成后,我们重启CASServer:./build.shrun启动成功后,在浏览器中输入https://cas.javaboy.org:8443/cas/login,进入登录页面(注意是httpsoh):此时登录用户名为javaboy,密码为123。2.3CASClient接下来我们来看看CASClient的改进。接下来的配置是基于SpringBoot的第三种方案实现单点登录!一篇,所以没看过上一篇的朋友建议先看一下。同时为了案例简单,我这里使用JPA来操作数据库。如果对这个操作不熟悉,可以参考本系列上一篇文章:SpringSecurity+SpringDataJpa强强联手,安全管理只为更简单!。CASClient中的对接主要是实现UserDetailsS??ervice接口。这里要用到数据库查询,所以我们先添加数据库相关的依赖:springframework.bootspring-boot-starter-data-jpa然后在application.properties中配置数据库连接信息:spring.datasource.username=rootspring.datasource.password=第123话updatespring.jpa.show-sql=truespring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect都是常规配置,不再赘述。接下来,我们创建两个实体类,分别代表用户角色和用户类:省略getter/setter}该实体类用于描述用户角色信息,包括角色id,角色名(英文,中文),@Entity表示这是一个实体类。项目启动后会在数据库中根据实体类的属性自动创建角色表。用户实体类:@Entity(name="t_user")publicclassUserimplementsUserDetails{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;privateStringusername;privateStringpassword;privatebooleanaccountNonExpired;privatebooleanaccountNonLocked;privatebooleancredentialsNonExpired;privatecadeFetch,@f=CascadeType.PERSIST)privateListroles;@OverridepublicCollectiongetAuthorities(){Listauthorities=newArrayList<>();for(Rolerole:getRoles()){authorities.add(newSimpleGrantedAuthority(角色。getName()));}returnauthorities;}@OverridepublicStringgetPassword(){returnpassword;}@OverridepublicStringgetUsername(){returnusername;}@OverridepublicbooleanisAccountNonExpired(){returnaccountNonExpired;}@OverridepublicbooleanisAccountNonLocked(){returnaccountNonLocked;}@OverridepublicbooleanisCredentialsNonExpired()}Nonreturncredentials@OverridepublicbooleanisEnabled(){returnenabled;}//省略其他get/set方法}用户实体类主要需要实现UserDetails接口,实现接口中的方法。这里的字段基本上很容易理解。先说几个比较特殊的:accountNonExpired,accountNonLocked,credentialsNonExpired,enabled是用来描述用户状态的,表示账户是否未过期,账户是否未被锁定,密码是否未过期,以及该帐户是否可用。roles属性表示用户的角色。User和Role是多对多的关系,用@ManyToMany注解来描述。getAuthorities方法返回用户的角色信息,我们可以在这个方法中稍微转换一下我们的Role。数据模型准备好之后,我们来定义一个UserDao:publicinterfaceUserDaoextendsJpaRepository{UserfindUserByUsername(Stringusername);}这里的事情很简单,我们只需要继承JpaRepository,提供一个根据用户名查询用户的方法即可。如果对SpringDataJpa的操作不熟悉,可以在公众号后台回复springboot获取松哥手敲的SpringBoot教程,里面有jpa相关的操作。也可以观看松哥录制的视频教程:SpringBoot+Vue系列视频教程。接下来定义UserService,如下:我们需要实现UserDetailsS??ervice接口。要实现这个接口,我们必须实现接口中的方法,即loadUserByUsername。OK,至此,我们的CASClient就开发完成了。接下来,启动CAS客户端。启动成功后,在浏览器中输入http://client1.cas.javaboy.org:8080/user/hello,进入hello界面。会自动跳转到CASServer登录,登录用户名和密码就是我们保存在数据库中的用户名和密码。登录成功后,经过两次重定向,会回到hello界面。hello界面访问成功后,再次进入/user/hello界面,会发现权限配置也生效了。这里比较简单,就不给大家截图了。3、小结好了,今天我主要和小伙伴们分享下如何在SpringSecurity+CAS单点登录中使用本地数据库。一个核心思想是认证由CASServer完成,权限相关的操作仍然由SpringSecurity完成。好吧,这就是本文的全部内容。本文相关案例我已经上传到GitHub,大家可以自行下载:https://github.com/lenve/spring-security-samples,可以通过以下二维码关注。转载本文请联系江南一点鱼公众号。