I'm using Spring Boot Parent version 1.5.16.
I need to use current user information and now I use #AuthenticationPrincipal annotation.
But I have to write this annotation for each method. I think this is not a best practice because I have more than 200+ methods. Is there any other suggestion to inject Authentication Principal globally or class level?
Related
I'm migrating an application with custom rest controllers to spring data rest. One problem I'm facing is that I had to add #PreAuthrozie annotations directly to my repositories instead of having them at a controller level. This is fine except some special cases.
The whole user repository is protected by a USER_ACCESS privilege. When the user authenticates, a new token is generated and the user has to be saved. Problem is, at this point there is no authentication in the Security Context so the request returns with 403
I have some code that on startup has all classes implementing PermissionProvider and saves new permissions to the database. Again, at this point there is no authentication in the Security Context so this fails since the repository is protected by PERMISSION_ACCESS privilege
I can manually create a tmp authentication that I set before the call then clear the context but this seems like a hack and can be problematic. Is there a way to disable #PreAuthorize in some context?
The only way you can work around this is to in cases 1. and 2. call another method in the repository that is not annotated with #PreAuthorize. This method would then call the methods annotated with #PreAuthorize. Since they are in the same class, #PreAuthorize has no effect. The reason being the way Spring AOP and CGLIB work. A proxy class is created that extends your class, providing the logic behind the #PreAuthorize behavior. When you call a method within the same class, such a call does not go through the proxy class, and as a consequence #PreAuthorize has no effect.
In spring boot, application.yml takes in the Spring oauth2 client config. How do I configure it for the non-boot application. By configuration I mean giving client ID, secret, scopes and redirect URI.
You could find an example here:
https://www.baeldung.com/spring-security-5-oauth2-login#non-boot
You need to:
Build your ClientRegistration.
A ClientRegistrationRepository.
Register your repository on WebSecurityConfigurerAdapter.
If you don't use SpringBoot : there is no application.yml and even if you can add the support of yml files. It won't handle your oauth2 client config.
Anyway you can use Spring security to implement your custom Authorization Service, a User service and implement a Token Store of your choice (JBDCTokenStore or JWTTokenStore for example). But It's a very wide question depending on your business logic.
You can find some well documented samples on :
https://github.com/spring-projects/spring-security-oauth/tree/master/spring-security-oauth2
Of course you can handle both XML and javaConfig even mixed Spring confugurations.
Create a #Configuration class with a #ComponentScan on the packages containing components or bean definitions.
#Configuration
#ComponentScan({ "com.firm.product.config.xml","com.firm.product.config.java" })
public class SpringConfig {
}
You can also set properties with #PropertySource() ans #Value annotations. It's very well documented.
This is more of a Spring JPA (Hibernate) related issue than AspectJ one, I believe.
Spring Boot v2.2.2.RELEASE, Spring v5.2.2.RELEASE, Hibernate v5.4.9.Final, Spring Data Repositories
I am trying to implement Multi-tenancy in my existing single tenant application.
The tenant is chosen by the users via front-end. The tenant id is
stored in HttpSession.
An advice for Rest Controller methods, reads
the tenant id and keeps it in a ThreadLocal variable.
Now I have to enable a Hibernate Filter using the tenant id. For this, an AspectJ advice for my Repository (interface extends JpaRepository) methods work, but gets executed for each repository method call from Service.
This post is about the following (identical) implementations where the advice for enabling Hibernate Filter is fired before the advice for reading the tenant id from HttpSession. How do I correct the order? The advice for reading the tenant id does not make any repository calls.
#AfterReturning(pointcut = "execution(* javax.persistence.EntityManagerFactory+.createEntityManager(..))", returning = "entityManager")
Ref: https://github.com/spring-projects/spring-framework/issues/25125 (This thread contains a non-AOP way also - post-processing transactional EntityManager instances - That gets triggered only when the Spring Boot starts)
#AfterReturning(pointcut="bean(entityManagerFactory) && execution(* createEntityManager(..))", returning="retVal")
Ref: Access to Session using Spring JPA and Hibernate in order to enable filters
I tried setting the application property spring.jpa.open-in-view=false, but that didn't help.
I want to use SpringSecurity4 in a CDI/EJB environment.
Is this possible? Can SpringSecurity can be used without using Spring?
What I want to do, is to use SpringSecurity with my EJB and CDI components.
Spring Security is basically a filter machine, filtering all the incoming requests. However, plenty of it's functionality is Spring-core dependent. It is possible to utilize Spring in a CDI application, but Spring's core is heavyweight and it's functionality is funny compared to CDI. That would be a downgrade and there would be no point in using CDI.
What you can do is to have a look at some Security projects for JEE world.
Apache DeltaSpike and it's Security module.
Keycloak - The absolute solution. Keycloak goes far, far beyond Spring security's functionality. It is an evolution of old PicketLink libraries developed by JBoss, but those are discontinued and merged into Keycloak instead. An example how simple usage of Keycloak is can be found here.
It is also not that hard to write own security interceptor using #WebFilter and #Inject :), there are several projects on GitHub:
https://github.com/rmpestano/security-interceptor
https://github.com/clairton/security
https://github.com/Rudin-Informatik/cdi-security
https://github.com/rafaelodon/my-security-context
I have no experience with these projects. However, I am always amazed how easily can Spring Security be replaced :)
I am using Spring Security with CDI but I can say it is not very healthy since Spring Security is based on spring and spring is messing with the CDI beans.
Here is what happened to me. I customized the AuthenticationProvider of spring security in order to authenticate users through my authentication server. When implementing this mechanism I used my predefined CDI beans by injecting them using (#Inject) annotation. At this point spring somehow intercepts the injection and creates its own bean, which means you cannot use any of the values you set to the CDI bean previously.
In order to solve this, I did some trick like this:
#Inject
private LoginController loginController;
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//Here, the injected bean is empty, I am requesting my old bean from CDI and assign it back.
LoginController bm = (LoginController) CDI.current().select(LoginController.class).get();
loginController = bm;
I don't know if this is the answer you are looking for but i hope this helps...
Definitely need some expert help with this! I think this is mainly a Spring Security question, but as I don't know for sure, so I am also tagging with the general Spring tag!
When the Application Context is loaded (mine is all via Java Config, though I don't believe that matters), the "DefaultListableBeanFactory" is processed and eventually (via the ProxyFactory) Spring Security Advisors are added. This is great when I have Spring Beans as I have Permissions that need authorization.
My question is: how do I get the same effect when I no longer require those classes to be Spring Beans? Said differently, if I have an object instance created as a singleton bean via Java Config and the authorization is working correctly, is it possible to maintain that with the object instance being a POJO? Again, for the experts, I want the interception chain returned in the JdkDynamicAopProxy to contain the Spring Security interceptors.
And "no", I am not really expecting an answer to this, maybe just hoping!!!
To add security interceptors to beans not instantiated by spring container
switch global-security tag to mode aspectj and weave the provided AnnotationSecurityAspect in the aspecj module.
For your second question I suppose that you want to do one of the following:
Use a ProxyFactoryBean to secure a bean.
Create security proxies programmatically: Use ProxyFactory.addAdvice() method.
Add the security interceptor to all proxies created by an AutoProxyCreator: This usually don't needed, but you can use the AbstractAutoProxyCreator.interceptorNames property to add common interceptors. The global-security tag parser uses a generated name for the MethodSecurityInterceptor, so you need to configure the interceptor manually and set a consistent SecurityMetadataSource.