Javaコードでユーザー権限または権限を確認する方法は?たとえば、役割に応じてユーザーのボタンを表示または非表示にします。次のような注釈があります。
@PreAuthorize("hasRole('ROLE_USER')")
Javaコードでそれを作る方法は?何かのようなもの :
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
Javaコードでユーザー権限または権限を確認する方法は?たとえば、役割に応じてユーザーのボタンを表示または非表示にします。次のような注釈があります。
@PreAuthorize("hasRole('ROLE_USER')")
Javaコードでそれを作る方法は?何かのようなもの :
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
HttpServletRequestオブジェクトのisUserInRoleメソッドを使用できます。
何かのようなもの:
public String createForm(HttpSession session, HttpServletRequest request, ModelMap modelMap) {
if (request.isUserInRole("ROLE_ADMIN")) {
// code here
}
}
SpringSecurity3.0にはこのAPIがあります
SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)
使用する前に、ラッパーを挿入する必要があります。
ループを使用してUserDetailsから権限を見つける代わりに、次のことができます。
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
boolean authorized = authorities.contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
セキュリティコンテキストを取得して、それを使用できます。
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
protected boolean hasRole(String role) {
// get security context from thread local
SecurityContext context = SecurityContextHolder.getContext();
if (context == null)
return false;
Authentication authentication = context.getAuthentication();
if (authentication == null)
return false;
for (GrantedAuthority auth : authentication.getAuthorities()) {
if (role.equals(auth.getAuthority()))
return true;
}
return false;
}
以下のようにhasRole()メソッドを実装できます-(これはSpring Security 3.0.xでテストされており、他のバージョンについては不明です)。
protected final boolean hasRole(String role) {
boolean hasRole = false;
UserDetails userDetails = getUserDetails();
if (userDetails != null) {
Collection<GrantedAuthority> authorities = userDetails.getAuthorities();
if (isRolePresent(authorities, role)) {
hasRole = true;
}
}
return hasRole;
}
/**
* Get info about currently logged in user
* @return UserDetails if found in the context, null otherwise
*/
protected UserDetails getUserDetails() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
userDetails = (UserDetails) principal;
}
return userDetails;
}
/**
* Check if a role is present in the authorities of current user
* @param authorities all authorities assigned to current user
* @param role required authority
* @return true if role is present in list of authorities assigned to current user, false otherwise
*/
private boolean isRolePresent(Collection<GrantedAuthority> authorities, String role) {
boolean isRolePresent = false;
for (GrantedAuthority grantedAuthority : authorities) {
isRolePresent = grantedAuthority.getAuthority().equals(role);
if (isRolePresent) break;
}
return isRolePresent;
}
私はこれを使用しています:
@RequestMapping(method = RequestMethod.GET)
public void welcome(SecurityContextHolderAwareRequestWrapper request) {
boolean b = request.isUserInRole("ROLE_ADMIN");
System.out.println("ROLE_ADMIN=" + b);
boolean c = request.isUserInRole("ROLE_USER");
System.out.println("ROLE_USER=" + c);
}
AuthorityUtilsクラスからいくつかのヘルプを得ることができます。ワンライナーとしての役割の確認:
if (AuthorityUtils.authorityListToSet(SecurityContextHolder.getContext().getAuthentication().getAuthorities()).contains("ROLE_MANAGER")) {
/* ... */
}
警告:ロール階層が存在する場合、これはロール階層をチェックしません。
ほとんどの答えはいくつかの点を欠いています:
春の役割と権限は同じではありません。詳細については、こちらをご覧ください。
ロール名はrolePrefix
+と同じauthority
です。
デフォルトの役割プレフィックスはですがROLE_
、構成可能です。ここを参照してください。
したがって、適切なロールチェックでは、ロールプレフィックスが設定されている場合はそれを尊重する必要があります。
残念ながら、Springでのロールプレフィックスのカスタマイズは少しハックで、多くの場所でデフォルトプレフィックスROLE_
がハードコーディングされていますが、それに加えて、タイプのBeanがGrantedAuthorityDefaults
Springコンテキストでチェックされ、存在する場合はカスタムロールプレフィックスが尊重されています。
このすべての情報をまとめると、より適切なロールチェッカーの実装は次のようになります。
@Component
public class RoleChecker {
@Autowired(required = false)
private GrantedAuthorityDefaults grantedAuthorityDefaults;
public boolean hasRole(String role) {
String rolePrefix = grantedAuthorityDefaults != null ? grantedAuthorityDefaults.getRolePrefix() : "ROLE_";
return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
.map(Authentication::getAuthorities)
.map(Collection::stream)
.orElse(Stream.empty())
.map(GrantedAuthority::getAuthority)
.map(authority -> rolePrefix + authority)
.anyMatch(role::equals);
}
}
JoseKからの回答は、HTTPリクエストへの参照からWebレイヤーとの結合を導入したくないサービスレイヤーにいる場合は使用できません。サービスレイヤーでの役割の解決を検討している場合は、Gopiの答えが最適です。
しかし、それは少し長い曲がりくねっています。認証から直接権限にアクセスできます。したがって、ユーザーがログインしていると想定できる場合は、次のようになります。
/**
* @return true if the user has one of the specified roles.
*/
protected boolean hasRole(String[] roles) {
boolean result = false;
for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
String userRole = authority.getAuthority();
for (String role : roles) {
if (role.equals(userRole)) {
result = true;
break;
}
}
if (result) {
break;
}
}
return result;
}
以下のこの2つの注釈は等しく、「hasRole」はプレフィックス「ROLE_」を自動的に追加します。正しい注釈があることを確認してください。この役割は、UserDetailsService#loadUserByUsernameで設定されます。
@PreAuthorize("hasAuthority('ROLE_user')")
@PreAuthorize("hasRole('user')")
次に、Javaコードでロールを取得できます。
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_user"))){
System.out.println("user role2");
}
不思議なことに、Spring-Securityアクセス制御はJavaベースではなく式ベースであるため、この問題に対する標準的な解決策はないと思います。DefaultMethodSecurityExpressionHandlerのソースコードをチェックして、 そこで行っていることを再利用できるかどうかを確認できます。
これはもう一方の端からの質問のようなものですが、これを見つけるためにインターネットを実際に掘り下げる必要があったので、私はそれを投げ込むと思いました。
ロールをチェックする方法についてはたくさんありますが、hasRole( "blah")と言うときに実際にチェックしていることはあまり言いません
HasRoleは、現在認証されているプリンシパルの付与された権限をチェックします
つまり、hasRole( "blah")を見ると、実際にはhasAuthority( "blah")を意味します。
私が見た場合、getAuthoritiesというメソッドを定義するUserDetailsを実装するクラスを使用してこれを行います。これでは、基本的に、new SimpleGrantedAuthority("some name")
いくつかのロジックに基づいてリストにいくつかを追加します。このリストの名前は、hasRoleステートメントによってチェックされるものです。
このコンテキストでは、UserDetailsオブジェクトが現在認証されているプリンシパルであると思います。認証プロバイダーとその周辺で発生する魔法がいくつかあります。具体的には、これを実現する認証マネージャーです。
遅くなったほうがいいですが、2セントの価値を入れさせてください。
JSFの世界では、マネージドBean内で、次のことを行いました。
HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
SecurityContextHolderAwareRequestWrapper sc = new SecurityContextHolderAwareRequestWrapper(req, "");
上で述べたように、私の理解では、次のように長い道のりで行うことができます。
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
userDetails = (UserDetails) principal;
Collection authorities = userDetails.getAuthorities();
}
@goukiの答えが一番です!
春が実際にこれを行う方法のほんの一例。
SecurityContextHolderAwareRequestWrapper
クラスを実装するという名前のクラスがありServletRequestWrapper
ます。
and searchユーザー(Springによって管理されている)をSecurityContextHolderAwareRequestWrapper
オーバーライドして、ユーザーがロールを持っているかどうかを確認します。isUserInRole
Authentication
SecurityContextHolderAwareRequestWrapper
コードは次のとおりです。
@Override
public boolean isUserInRole(String role) {
return isGranted(role);
}
private boolean isGranted(String role) {
Authentication auth = getAuthentication();
if( rolePrefix != null ) {
role = rolePrefix + role;
}
if ((auth == null) || (auth.getPrincipal() == null)) {
return false;
}
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
if (authorities == null) {
return false;
}
//This is the loop which do actual search
for (GrantedAuthority grantedAuthority : authorities) {
if (role.equals(grantedAuthority.getAuthority())) {
return true;
}
}
return false;
}
私たちのプロジェクトでは、役割階層を使用していますが、上記の回答のほとんどは特定の役割をチェックすることのみを目的としています。つまり、指定された役割のみをチェックし、その役割と階層の上位はチェックしません。
これに対する解決策:
@Component
public class SpringRoleEvaluator {
@Resource(name="roleHierarchy")
private RoleHierarchy roleHierarchy;
public boolean hasRole(String role) {
UserDetails dt = AuthenticationUtils.getSessionUserDetails();
for (GrantedAuthority auth: roleHierarchy.getReachableGrantedAuthorities(dt.getAuthorities())) {
if (auth.toString().equals("ROLE_"+role)) {
return true;
}
}
return false;
}
RoleHierarchyは、spring-security.xmlでBeanとして定義されています。
ユーザーロールは、次の方法で確認できます。
SecurityContextHolderで静的メソッドの呼び出しを使用する:
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_NAME"))) { //do something}
HttpServletRequestの使用
@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
if (request.isUserInRole("ROLE_NAME")) {
}
ユーザーモデルに、以下のような「hasRole」メソッドを追加するだけです。
public boolean hasRole(String auth) {
for (Role role : roles) {
if (role.getName().equals(auth)) { return true; }
}
return false;
}
私は通常、認証されたユーザーが次のように管理者の役割を持っているかどうかを確認するために使用します
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // This gets the authentication
User authUser = (User) authentication.getPrincipal(); // This gets the logged in user
authUser.hasRole("ROLE_ADMIN") // This returns true or false
Java8の助けを借りた私のアプローチ、コマ分離された役割を渡すことはあなたに真または偽を与えるでしょう
public static Boolean hasAnyPermission(String permissions){
Boolean result = false;
if(permissions != null && !permissions.isEmpty()){
String[] rolesArray = permissions.split(",");
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
for (String role : rolesArray) {
boolean hasUserRole = authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(role));
if (hasUserRole) {
result = true;
break;
}
}
}
return result;
}
SpringSecurityで注釈@Secured
または@RolesAllowed
または@PreAuthorise
/@PostAuthorise
を使用できます。
注意:このコードを追加する必要があります
@Configuration
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class MyConfig extends WebSecurityConfigurerAdapter{
}
configureクラスの前。securedEnabled
3つのパラメータ、、、jsr250Enabled
のすべてを使用する必要はありませんprePostEnabled
。使用する注釈に応じて1つだけ必要です。
次に、コントローラークラスにロールチェックアノテーションを配置します。
@Secured("ROLE_admin")
@GetMapping("/hello")
public String hello(){
return "hello";
}
また
@RolesAllowed("ROLE_admin")
@GetMapping("/hello")
public String hello(){
return "hello";
}
また
@PreAuthorize("hasRole('ROLE_user')")
@GetMapping("/hello")
public String hello(){
return "hello";
}
これがチュートリアルですhttps://www.baeldung.com/spring-security-method-security