is there any possibility to remove a provider in the build process?
I tried to hook in the "ResteasyDeploymentCustomizerBuildItem" in the following way:
deploymentCustomizerProducer.produce(new ResteasyDeploymentCustomizerBuildItem(new Consumer<ResteasyDeployment>() {
#Override
public void accept(ResteasyDeployment resteasyDeployment) {
resteasyDeployment.getProviderClasses().remove("my.testpackage.TestProvider");
}
}));
But in my opinion the removement is ignored and the provider is registered!
Thanks in advance for your tips!
Related
I consume messages from spring-cloud-stream through a Consumer<MyMessage> Implementation. As part of the message handling I need to access methods that are protected with #PreAuthorize security-checks. By default the Consumer run unauthenticated so message-handling fails.
Consumer:
#Bean
public Consumer<MyMessage> exampleMessageConsumer(MyMessageConsumer consumer) {
return consumer::handleMessage;
}
Secured Method:
#PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
public void doSomething() { ... }
I dont just want to bypass security, so what is the easiest way to authenticate my Consumer so it passes the check?
EDIT: we are using google pubsub as a binder
For the Kafka binder:
Add an #EventListener to listen for ConsumerStartedEvents; you can then add the authentication to the security context via the SecurityContextHolder; this binds it to the thread; the same thread is used to call the listener.
I found two possible solutions to my problem
use springs RunAs support (baeldung) to add permissions to a security context for a specific method. If i do this i need to add ROLE_RUN_AS_USER to my secured methods. At scale this would complicated annotations a lot.
Manually change the security context before executing the handler method and return it to its original state afterwards.
I went with the second option. I would have liked a transparent solution but there does not appear to be one.
To make this work i created a class that wraps a functional interface with the changing code and returns it.
public class RunAs {
#FunctionalInterface
public interface RunAsMethod {
void runWithException() throws Throwable;
}
public static <T> Consumer<T> createWriteConsumer(Consumer<T> originalConsumer) {
return message -> runWithWritePermission(() -> originalConsumer.accept(message));
}
public static void runWithWritePermission(final RunAsMethod func) {
final Authentication originalAuthentication = SecurityContextHolder.getContext().getAuthentication();
final AnonymousAuthenticationToken token = new AnonymousAuthenticationToken(
"system",
originalAuthentication != null ? originalAuthentication.getPrincipal() : "system",
AuthorityUtils.createAuthorityList("ROLE_ADMIN", "SCOPE_write")
);
SecurityContextHolder.getContext().setAuthentication(token);
try {
func.runWithException();
} catch (Throwable e) {
throw new RuntimeException("exception during method with altered permissions", e);
} finally {
SecurityContextHolder.getContext().setAuthentication(originalAuthentication);
}
}
}
I have slight issue with step customization. I want to add some specific data from Spring context to JBehave report after successful step executing, e.g. I have step:
When login as random user
I want to see in report if all was good something like
When login as random user (%username%)
I found how to execute any logic before/after story/scenario, but I can't find correct way how to add any logic after step and how can I customize/extend basic JBehave steps.
Thank you in advance.
Use StoryReporter API:
import org.jbehave.core.reporters.NullStoryReporter;
public class MyCustomStoryReporter extends NullStoryReporter {
#Override
public void beforeStep(String step) {
// add "before-step" logic here
}
#Override
public void successful(String step) {
// add "after-passed-step" logic here
}
#Override
public void failed(String step, Throwable cause) {
// add "after-failed-step" logic here
}
}
More information on StoryReporter and its configuration can be found in the official documentation: Reporting Stories
I've been trying to override Stormpath's RequestEventListenerAdapter methods to populate an account's Custom Data when the user logs in or creates an account.
I created a class that extends RequestEventListenerAdapter and am trying to override the on SuccessfulAuthenticationRequestEvent and the on LogoutRequestEvent to make some simple outputs to the console to test if they are working (A simple "Hello world!" for example). But when I do any of these actions on the application, none of these events are triggering. So I was wondering if anyone here could help me out, I'm not sure if the bean I'm supposed to declare is in the right place or if I'm missing some kind of configuration for the events to trigger. Thanks for any help and let me know if more information is needed.
This is my custom class:
import com.stormpath.sdk.servlet.authc.LogoutRequestEvent;
import com.stormpath.sdk.servlet.authc.SuccessfulAuthenticationRequestEvent;
import com.stormpath.sdk.servlet.event.RequestEventListenerAdapter;
public class CustomRequestEventListener extends RequestEventListenerAdapter {
#Override
public void on(SuccessfulAuthenticationRequestEvent e) {
System.out.println("Received successful authentication request event: {}\n" + e);
}
#Override
public void on(LogoutRequestEvent e) {
System.out.println("Received logout request event: {}\n" + e);
}
}
This is the bean that I'm not sure where to place:
#Bean
public RequestEventListener stormpathRequestEventListener() {
return new CustomRequestEventListener();
}
What you are doing looks exactly right. I have created a sample project demonstrating how to get things working. You could take a look at it (it is very simple) and compare it with what you have.
I also added instructions on how to get it running so you can see that it does indeed work.
I am using spring.security.version = 3.1.0.RELEASE. The problem I am having is that for some reason AuthenticationFailureCredentialsExpiredEvent is not fired.
While debugging the code I found that AbstractUserDetailsAuthenticationProvider do display in the console that "User account credentials have expired". But I am still baffling as to why the event in concern is not triggered.
Here is my code:
class JpaUserDetails implements UserDetails {
...
...
#Override
public boolean isCredentialsNonExpired() {
if (some logic) {
return true;
}
else {
return false;
}
}
}
I do see AbstractUserDetailsAuthenticationProvider displaying in the console "User account credentials have expired" from the following lines of spring code:
public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitilizeBean, MessageSourceAware {
...
...
private class DefaultPostAuthenticationChecks implements UserDetailsChecker {
public void check(UserDetails user) {
if(!user.isCredentialsNonExpired()) {
logger.debug("User account credentials have expired");
throw new CredentialsExpiredException(message.getMessage(
"AbstractUserDetailsAuthenticationProvider.credentialsExpired",
"User credentials have expired"), user);
}
}
}
}
The issue is that when the user credentials have expired, I am expecting the Spring to generate the event AuthenticationFailureCredentialsExpiredEvent which I am handling in the following way:
class SecurityEventDispatcher implements ApplicationListener<ApplicationEvent> {
final List<SecurityEventListener> listeners = new ArrayList<SecurityEventListener>();
public void registerListener(SecurityEventListener listener) {
this.listener.add(listener);
}
public void onApplicationEvent(ApplicationEvent event) {
for (SecurityEventListener listener : this.listeners) {
if(listener.canHandle(event)) {
listener.handle(event);
}
}
}
}
This is how I am handling the login failure event:
public class LoginFailedEvent extends SecurityEventListener {
#Override
public boolean canHandle(Object event) {
if(event instanceof AbstractAuthenticationFailureEvent) {
return true;
}
else {
return false;
}
}
#Override
public void handle(Object event) {
if (event instanceof AuthenticationFailureBadCredentialsEvent) {
// do something
}
if (event instanceof AuthenticationFailureCredentialsExpiredEvent) {
// do something
}
}
}
The issue as I mentioned before is that AuthenticationFailureCredentialsExpiredEvent is never fired. I have tested the AuthenticationFailureBadCredentialsEvent which works fine.
This is what I get in event for bad credentials: (which is working fine)
org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent
This is what I get in event for expired password:
ServletRequestHandledEvent: url=[/app/loginFailure] with failureCause = null
Does anyone have any idea what could be wrong? Any help will be highly appreciated.
Here is the answer to this question, since there isn't any much literature out there regarding the issue.
You probably need to set the ProviderManager's
('s) eventPublisher to be something other than
NullEventPublisher. There is not a simple way to do this via the
tag, so you will want to create the
AuthenticationProvider using standard beans configuration and inject
it into a standard Spring Bean for the ProviderManager.
Rob Winch - Spring Security Lead
If anyone is running into this issue, just upgrade the spring security to 3.1.2 or +, the issue is fixed.
(Applies to Spring Security 5)
Spring's default publisher is the NullEventPublisher. This will effectively publish nothing.To get events please configure a
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
#Bean
public DefaultAuthenticationEventPublisher defaultAuthenticationEventPublisher() {
return new DefaultAuthenticationEventPublisher();
}
Now the events a published and one can just consume them as any other event:
#EventListener
public void logAuditEvents(AbstractAuthenticationEvent event) {
...
}
and
#EventListener
public void logAuditEvents(AbstractAuthorizationEvent event) {
...
}
I would like to experiment with NServiceBus using ASP.NET MVC 3. I've got a solution with NServiceBus installed, plus NinjectMVC3 and NServiceBus.Ninject-CI. Trouble is, I have no idea how to setup NServiceBus stuff in the NinjectMVC3.cs file in App_Start.
Rather annoyingly I'm having trouble finding any examples of how to use NServiceBus.Ninject-CI (I hate it when people don't bother giving examples of how to use their stuff).
Can someone help me get started please?
Load a module like this into the kernel to provide access to the bus
public class NServiceBusModule : NinjectModule
{
public override void Load()
{
this.Bind<IBus>().ToConstant(this.CreateBus()).InSingletonScope();
}
private IBus CreateBus()
{
return NServiceBus.Configure.WithWeb()
.NinjectBuilder(this.Kernel)
... // put NServiceBus config here
.CreateBus()
.Start();
}
}
Read the NServiceBus documentation about how to configure NServiveBus:
http://docs.particular.net/nservicebus/containers/ninject
http://docs.particular.net/samples/web/asp-mvc-application/
Hopefully this will help someone. I had a lot of trouble finding sample code for getting ninject working within NServiceBus.
This code below works for me in place of the more common Castle version:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
#region IWantCustomInitialization Members
public void Init()
{
Configure
.With()
.NinjectBuilder(CreateKernel())
.XmlSerializer()
.MsmqTransport();
SetLoggingLibrary.Log4Net(XmlConfigurator.Configure);
}
protected IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load<MyCustomNinjectModule>();
return kernel;
}
#endregion
}
with the ninject module being the usual format, ie:
public class MyCustomNinjectModule : NinjectModule
{
public override void Load()
{
Bind(typeof(ILogger<>)).To(typeof(Log4NetLogger<>));
...
}
}