I have been able to implement the #Secured annotation in one controller of my application. Yet, #Secured('ROLE_ADMIN') will NOT work anywhere else within the project.
It will only specifically work anywhere within my program controller and no where else.
For example, if I use it as so;
#Secured('ROLE_ADMIN')
The IDE gives me;
Multiple markers at this line
- Groovy:class Secured is not an annotation in #Secured
- Groovy:unable to resolve class Secured , unable to find class for
I have even tried checking the Spring Security Config file to check if annotations were set correctly (which seemingly they were).
Any ideas? Please help.
Thanks.
You are probably missing the required import.
At the top of each controller where you need the annotations use the grails import for Secured. Then you can use the annotations for the class or method as needed.
import grails.plugin.springsecurity.annotation.Secured
//import grails.plugins.springsecurity.Secured; - this is in older version,
// grails 2.0 and older
#Secured(['ROLE_ADMIN', 'ROLE_USER', 'ROLE_SUPERVISOR'])
class myClass {
}
Hope this helps.
Try this:
#PreAuthorize("hasRole('ROLE_ADMIN')" )
And add annotation support in spring configuration:
<!-- Allow configuration annotation (#Annotation-based configuration)-->
<context:annotation-config />
<!-- Enable scan classes -->
<context:component-scan base-package="com.your.package" />
Related
I have a spring boot rest service that included an external project in pom as it's dependency. That external project is basically a jar that has spring AOP code.
The base package in my main application that includes this external jar with spring AOP code is x.y.z
The class in external jar where the #before advice is, is under the package a.b.c
With this class under a.b.c package, it doesn't get recognized by the main application where I want to use the spring aop implementation and apply the aspect. However, when I change it's package from a.b.c to x.y.z (which I really can't do in real life) it works fine.
I know that in spring boot service which happens to be the including service, it scans everything under root package given in the application class, x.y.z in this case and that is why aspect works fine if it's class is under x.y.z.
however, the problem is that this spring app jar will be used across multiple applications. So changing package name like this is not an option.
Is there a way to accomplish this without changing the package name of the class where spring app code is ?
Probably component scan is only activated for your application class packages by default. You can extend it to multiple packages, including the aspect package:
XML style configuration:
<context:component-scan base-package="x.y.z, a.b.c" />
Annotation style configuration:
#ComponentScan(basePackages = {"x.y.z", "a.b.c"})
Disclaimer: I am not a Spring user, only an AspectJ expert. I just knew that you can configure component scan, googled the syntax for you and hope it is correct.
Please define the bean (of jar project )inside main application. Give the #ComponentScan(basePackages = {"x.y.z", "a.b.c"}) as well as #EnableAspectJAutoProxy. Also include below piece of code.
ex:
` #Bean
public LoggingHandler loggingHandler()
{
return new LoggingHandler();
}`
Also annotate external jar code with:
`#Aspect
#Component
public class LoggingHandler {`
What #kriegaex suggests is correct. In addition to that, please make sure you are using #Component along with #Aspect. Since #Aspect is not a Spring annotation, Spring won't recognize it and hence your aspect won't be registered. So, using #Component is mandatory to getting aspects to work in Spring environment.
I've already done a simple project on spring mvc framework with XML config file. Now I want to add spring security with java config file in that project. Is it possible to integrate. I've almost spend a whole day searching it on google. I've already read documentation but I didn't get any clue. Can anyone provide me good reference for it? Thanks in advance
You have 2 options depending on which is leading, the XML or Java version. Both of them are quite well documented in the Spring Reference Guide.
When using XML you can simply add the #Configuration annotated class as a bean to the XML configuration like any other bean.
<bean class="your.configuration.class.Here" />
You have to have <context:annoation-config /> to have the #Configuration class processed.
However if you already have <context:component-scan /> and the package(s) you are scanning already includes the package that contains the #Configuration class you don't need to do anything as it will be detected like any other #Component.
If you want you have your #Configuration class leading then you can simply import the XML configuration using #ImportResource.
#Configuration
#ImportResource("your-configuration-here.xml")
public class SecurityConfig {}
Either way will work, which depends on which you want to make the leading configuration standard.
I have written some code in order test integration with mongoDB. Please find the link to the main method for running this spring boot application below,
https://github.com/siva54/simpleusercontrol/blob/master/src/main/java/com/siva/UserManagementApplication.java
From what I have read, An application should contain any of the configurations from the following URL to declare how the applications manages the context,
http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/using-boot-using-springbootapplication-annotation.html
I haven't used any of those contexts, However my application works fine and I'm able to run it without any issues. Am I missing something here? Can you please help with the info of how my application is able to start and manage the context/dependencies automatically?
Thanks in advance
#SpringBootApplication is equivalent of #Configuration, #EnableAutoConfiguration and #ComponentScan. Let's consider why your application works without of any of this three annotations.
Why it works without #Configuration:
When Spring will scan packages, it will find all classes marked by #Configuration and will use them as part of configuration. But in next line you manually passed UserManagementApplication as configuration source:
SpringApplication.run(UserManagementApplication.class, args);
So spring doesn't need to find this class by scan. Therefor it is not necessary to mark it by #Configuration.
Why it works without #ComponentScan:
Class UserManagementApplication has #ImportResource("classpath:spring/application-context.xml") annotation. That means file spring/application-context.xml will be included into configuration. And this file contains next line:
<context:component-scan base-package="com.siva.*" />
So, you don't need use annotation for scan packages, because you already declared it in the xml file.
Why it works without #EnableAutoConfiguration:
This annotation allows to Spring to try guess and configure the components automatically. For example, if you include the following dependency in your build.gradle:
dependencies {
compile 'org.springframework.boot:spring-boot-starter-data-mongodb'
}
Spring configures all the components required to work with MongoDB automatically. And all you need just specify host and user/pass in the aplication.proprties file.
But you preferred to declare all needed beans manually in the spring/application-context.xml file. So, you simply don't need #EnableAutoConfiguration annotation at all.
I have spring security application in which want to enable annotations security (pre and post authorization).
I also have small sample application in which i have implemented it already. Everything works.
But moving configs to main applications failed. There is no errors in console. But annotations do not work. It seems, they are not readed at all.
All configuration and component versions are completely the same.
There are
<security:global-method-security secured-annotations="enabled" />
records in security-context and servlet-context.
But neither #Controller methods no #Service methods are secured with annotation in main application.
How can i debug it?
Solved!
After switch from < global-method-security secured-annotations="enabled" /> to
pre/post annotations works fine.
You can add to your application.yaml:
logging.level.org.springframework.security: DEBUG
Or add to application.properties:
logging.level.org.springframework.security=DEBUG
Or add to your WebSecurityConfig annotation EnableWebSecurity with debug = true:
#Configuration
#EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// ...
}
Set the log level of org.springframework.security to debug. On invoking the method with annotations, you can find log messages that indicate interceptor being applied, especially look for:
DEBUG MethodSecurityInterceptor
Updated:
That means there is some config difference between your sample app and main app
Some pointers to look for:
the <global-method-security> tag needs to be in the same context as your Spring MVC configuration otherwise your controllers will not be post processed. Refer:
http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/faq.html#faq-method-security-in-web-context
you might need pre-post-annotations="enabled", with expressionHandler set.
make sure tag <global-method-security> is in application context
In case you just want to know, which method failed, simply set the logging level for this exception filter:
logging.level.org.springframework.security.web.access.ExceptionTranslationFilter: TRACE
It will only show the stack trace with the failed method and not spam your logs more than necessary ;-)
I've created a custom annotation (in Spring 3.05) that works great. I'd like to take that code and make it part of a library, packaged in a jar file, so I don't have to include my custom annotation code in each web app I write.
I'm unable to get Spring to act on the annotation, however. My library jar is in my web app's classpath and I tried scanning for it in applicationContext.xml:
<context:component-scan base-package="my.annotation.pkg" />
The field annotated with my custom annotation continues to be null.
Ideally I'd like to this to just work with a minimum of fuss and configuration, but so far I haven't had any success.
What part of Spring's wiring am I missing to get my custom annotation recognized when it's part of an external library?
Update
Here is how I "solved" it...just had to read a little more closely. In each context file (i.e. applicationContext.xml, dispatch-servlet.xml) I added the line:
<bean class="my.annotation.CustomInjector" />
...where my CustomInjector implements BeanPostProcessor. I based this on the code at this blog post: Implementing Seam style #Logger injection with Spring.
The author says I needed to do exactly what I did, so bad on me for not reading thoroughly. Why, though, is adding that bean definition required? Maybe Spring annotations are configured similarly under the hood - I just don't get why having the jar file on the classpath isn't enough.
Is your custom annotation annotated with the #Component annotation? From the Spring reference manual:
By default, classes annotated with #Component, #Repository, #Service, #Controller, or a custom annotation that itself is annotated with #Component are the only detected candidate components.
Alternatively, you could add a custom include-filter to the component-scan element in your XML configuration.