how keeping primefaces theme for all pages and session with spring security - primefaces

I work with maven and netbeans 8.2. In maven pom I have:
org.primefaces/primefaces/7.0
org.primefaces.themes/all-themes/1.0.10
In my Login.xhtml page, I used themeSwitcher for the selection of a theme that the user can keep it during the whole session, without keeping theme in a database table, I was inspired by following primefaces showcase : here
The change take effect only after login, when I make change theme for all pages in my index page. In my HttpSecurity configuration, I have put :
.formLogin().loginPage("/login.xhtml").permitAll()
I'm new with jsf and java.
Thank you in advance for your assistance

That work, only after user login and put :
web.xml
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>#{themeSwitcherView.theme}</param-value>
</context-param>
and initialise variable theme in
#PostConstruct
public void init() {
theme="omega";
themes = service.getThemes();
}
...
public String getTheme() {
return theme;
}
public void setTheme(String theme) {
this.theme = theme;
}
public void saveTheme(AjaxBehaviorEvent ajax) {
setTheme((String) ((ThemeSwitcher)ajax.getSource()).getValue());
}

Related

inject model data into spring webflow in cas

I am upgrading a CAS 4 to a CAS 6. I have done several Spring Boot 2 apps, so I know what I am doing there. I can even do some webflow, but only from scratch.
The documentation clearly states not to mess with the base webflow xml, and to "inject" your own services.
How does one "inject" a service? I really just need to add a message of the day to the login page.
Does anyone have an example of something this simple?
Find below my approach, tested on a cas-maven-overlay installation with cas version at 5.3.x. Some things maybe different on cas 6 branch but I assume the main idea remains.
First, we should create an Action class that will be injected in the login flow and will add the desired message in the flow scope in order to be available at the template(view).
public class DailyMessageAction extends AbstractAction{
#Override
protected Event doExecute(RequestContext context) throws Exception {
context.getFlowScope().asMap().put("dailyMessage", "YOUR_AWESOME_MESSAGE");
return success();
}
}
Then create a WebflowConfigurer class and inject our newly created DailyMessageAction in the actions list(see doInitialize method).
public class DailyMessageWebflowConfigurer extends AbstractCasWebflowConfigurer{
final Action dailyMessageAction;
public DailyMessageWebflowConfigurer(FlowBuilderServices flowBuilderServices,
FlowDefinitionRegistry flowDefinitionRegistry,
ApplicationContext applicationContext,
CasConfigurationProperties casProperties,Action dailyMessageAction){
super(flowBuilderServices, flowDefinitionRegistry, applicationContext, casProperties);
this.dailyMessageAction = dailyMessageAction;
}
#Override
protected void doInitialize() {
final Flow flow = super.getLoginFlow();
flow.getStartActionList().add(dailyMessageAction);
}
}
After that we should inject DailyMessageWebflowConfigurer in cas runtime. This is achieved by creating a configuration class and inject our configurer.
#Configuration
public class CustomWebflowConfiguration {
#Autowired
private CasConfigurationProperties casProperties;
#Autowired
#Qualifier("loginFlowRegistry")
private FlowDefinitionRegistry loginFlowDefinitionRegistry;
#Autowired
private ApplicationContext applicationContext;
#Autowired
private FlowBuilderServices flowBuilderServices;
#RefreshScope
#ConditionalOnMissingBean(name = "dailyMessageAction")
#Bean
public Action dailyMessageAction(){
return new DailyMessageAction();
}
#ConditionalOnMissingBean(name = "dailyMessageWebflowConfigurer")
#Bean
#RefreshScope
public CasWebflowConfigurer dailyMessageWebflowConfigurer(){
final DailyMessageWebflowConfigurer w = new DailyMessageWebflowConfigurer(flowBuilderServices,
loginFlowDefinitionRegistry,
applicationContext,
casProperties,
dailyMessageAction());
w.initialize();
return w;
}
}
Include our CustomWebflowConfigurationclass in META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=your_package.CustomWebflowConfiguration
The final step is to present the added message in the view. Achieved by adding this line
<div th:utext="${dailyMessage}"></div>
in the templates/casLoginView.html file.
... add a message of the day to the login page...
Modifying the spring webflow directly is not recommended in CAS. read this for more info
So if I were you instead of tinkering with spring webflow, I would try to do something like the following:
Note:
Bare in mind this might not be the recommended way to do so, but I think this will work, and much less work than overriding spring webflow
As you said you are quite familiar with Spring boot, so I won't bored you with detail implementation, I can follow up if you / other reader are confused
If your message of the day can be hard coded, just skip 1-3 and go straight with 4.
Ok here we go:
Override the CasSupportActionsConfiguration, only adding the initialFlowSetupAction bean
Adding a custom class (let named it MyInitialFlowSetupAction) and implement the InitialFlowSetupAction
In MyInitialFlowSetupAction, add something like this:
#Override
public Event doExecute(final RequestContext context) {
Event returnEvent = super.doExecute(context);
configureMyAwesomeMessageOfTheDay(context)
return returnEvent;
}
private void configureMyAwesomeMessageOfTheDay(final RequestContext context) {
String messageOfTheDay = "Spring is the best season!";//Your logic here
context.getFlowScope().put("MESSAGE_OF_THE_DAY", messageOfTheDay);
}
4 . CAS 6 is using WAR overlay, so you can overlay the html file, including this one
https://github.com/apereo/cas/blob/v6.0.3/webapp/resources/templates/casLoginView.html
overlay that file, and add your MESSAGE_OF_THE_DAY to it
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout}">
...
<body class="login">
<main role="main" class="container mt-3 mb-3">
Message of the day is: ${MESSAGE_OF_THE_DAY}
...
</main>
</body>
</html>
See if this helps you

How to get data from settings json to mvc 6 view?

I want to load all settings key value pair from json file at once and use the settings key value in mvc 6 view page where required.I would be grateful if best solution is provided.I have a scenerio as below
if(Settings.enable_logo_text)
{
<span>Settings.logo_text</span>
}
The official documentation regarding the new configuration and options is quite good, I would recommend having a look there first.
Following the guidance provided there, start by creating a POCO class for your settings:
public class Settings
{
public string logo_text { get; set; }
public bool enable_logo_text { get; set; }
}
Update the ConfigureServices method of your startup class so you read your settings from the configured Configuration and is then available as a service that can be injected wherever you need to:
public void ConfigureServices(IServiceCollection services)
{
...
services.Configure<Settings>(Configuration);
services.AddOptions();
}
If you want to use a the appsettings.json file, make sure you also build your Configuration object including that json file. For example:
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
}
This way you can configure your values in the appsettings.json file and the values will be set on your Settings class:
{
...
"enable_logo_text": true,
"logo_text": "My Logo Text"
}
Finally, you can access the configured values by adding a IOptions<Settings> dependency. The most straightforward way would be to directly inject the options into the view (as explained in the docs), but you might want to consider injecting the options into the controller and passing them to the view in a more controlled way:
#inject IOptions<Settings> Settings
...
#if(Settings.Value.enable_logo_text)
{
<span>#Settings.Value.logo_text</span>
}

Unable to access HTML files from spring MVC

I am writing basic spring mvc application which have no xml configuration its annotation based. I am trying to access html files like
" localhost:9090/help.html " but i get error
No mapping found for HTTP request with URI [/help.html] in DispatcherServlet with name 'dispatcher'
here is my config
#EnableWebMvc
#Configuration
#ComponentScan({ "com.example.test" })
public class WebConfig extends WebMvcConfigurationSupport {
#Bean
public InternalResourceViewResolver internalResourceViewResolver(){
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/jsp/");
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/*");
registry.addResourceHandler("/**/*").addResourceLocations("/templates/*");
}
}
my html pages are inside
webapp->templates
i have tried many question here but none helped and all of them relates to xml config
any suggestions ??
Ok I figured this out. It was just a silly mistake. In addResourceLocations i removed * at the end and bingo issued resolved
so this is wrong
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/*");
correct form is
registry.addResourceHandler("/resources/**").addResourceLocations("/resources");
Now i can access html pages directly like
localhost:8080/resources/help.html
even this is possible now
localhost:8080/help.html
because i have added another resource-handler as addResourceHandler("/*\*/**")

Configure a component in ASP.Net 5

There are differents ways to configure a component in ASP.Net 5 :
the AddXXX method, used for adding services,
the ConfigureXXX method, used for configuring the options,
the UseXXX method, use to register a middleware into the pipeline.
The ConfigureXXX() method has the responsability to configure a component or a subcomponent :
https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs#L12
public static IServiceCollection ConfigureAuthorization(
[NotNull] this IServiceCollection services,
[NotNull] Action<AuthorizationOptions> configure)
{
return services.Configure(configure);
}
https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs#L50
public static void ConfigureMvc(
[NotNull] this IServiceCollection services,
[NotNull] Action<MvcOptions> setupAction)
{
services.Configure(setupAction);
}
But sometimes the ConfigureXXX is a bit more complex :
https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs#L31
public static IServiceCollection ConfigureCookieAuthentication(
[NotNull] this IServiceCollection services,
[NotNull] IConfiguration config,
string optionsName)
{
return services.Configure<CookieAuthenticationOptions>(config, optionsName);
}
Why some existings components are more "configurables" than others ?
As a component writer, what should I practice?
Another related question :
AddXXX & UseXXX sometimes allows to configure the component :
https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs#L32
public static IMvcBuilder AddMvcCore(
[NotNull] this IServiceCollection services,
[NotNull] Action<MvcOptions> setupAction)
{
ConfigureDefaultServices(services);
AddMvcCoreServices(services);
services.Configure(setupAction);
return new MvcBuilder() { Services = services, };
}
https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs#L22
public static IApplicationBuilder UseOAuthAuthentication(
[NotNull] this IApplicationBuilder app,
[NotNull] string authenticationScheme,
Action<OAuthAuthenticationOptions> configureOptions = null)
{
return app.UseMiddleware<OAuthAuthenticationMiddleware<OAuthAuthenticationOptions>>(
// [...]
}
Basically, what is the sementic difference between configuring the options with the three differents methods ? Especially when it is available on the same component.
So with options and any component that's using the IOptions service, the idea was to make it easy to configure options at any point in the stack (Add, Use, Configure) they are all valid, but order does matter.
The general pattern we've been using is generally taking Action<YourOptions> wherever it might seem useful.

Nancy on ASP.NET vNext does not load the Nancy.Viewengines.Razor viewengine

I am trying Nancy with ASP.NET vNext on debian. I've setup a sample project and got it to work with a self hosted Owin application.
Nancy it self seem to run fine but it is looking for the views in the K runtime directory and the Razor viewengine won't load.
K does not show the Nancy.Viewengines.Razor being loaded altho it is in the project.json file
This is the error that I'm getting:
Nancy.RequestExecutionException: Oh noes! ---> Nancy.ViewEngines.ViewNotFoundException: Unable to locate view 'ViewTest'
Currently available view engine extensions: sshtml,html,htm
Locations inspected: views/Home/ViewTest-nl-NL,views/Home/ViewTest,Home/ViewTest-nl-NL,Home/ViewTest,views/ViewTest-nl-NL,views/ViewTest,ViewTest-nl-NL,ViewTest
Root path: /home/vnext/.kre/packages/KRE-mono45-x86.1.0.0-alpha3/bin/
If you were expecting raw data back, make sure you set the 'Accept'-header of the request to correct format, for example 'application/json' at Nancy.ViewEngines.DefaultViewFactory.GetRenderedView (string,object,Nancy.ViewEngines.ViewLocationContext) <0x008a3>
.
My project.json:
{
"dependencies": {
"Microsoft.Owin.Hosting": "2.1.0-*",
"Microsoft.Owin.Hosting": "2.1.0-*",
"Microsoft.Owin.Host.HttpListener": "2.1.0-*",
"Nancy": "0.23.2-*",
"Nancy.Owin": "0.23.2-*",
"Nancy.Viewengines.Razor": "0.23.2-*",
},
}
Loaded library's:
vnext#vnext:~/test/src$ k run
/home/vnext/.kre/packages/KRE-mono45-x86.1.0.0-alpha3/bin/klr.host.dll Information : 0 : [LoaderContainer]: Load name=Microsoft.Owin.Host.HttpListener
/home/vnext/.kre/packages/KRE-mono45-x86.1.0.0-alpha3/bin/klr.host.dll Information : 0 : [DefaultLoaderEngine]: LoadFile(/home/vnext/.kpm/packages/Microsoft.Owin.Host.HttpListener/2.1.0/lib/net45/Microsoft.Owin.Host.HttpListener.dll)
/home/vnext/.kre/packages/KRE-mono45-x86.1.0.0-alpha3/bin/klr.host.dll Information : 0 : [NuGetAssemblyLoader]: Loaded name=Microsoft.Owin.Host.HttpListener in 1ms
/home/vnext/.kre/packages/KRE-mono45-x86.1.0.0-alpha3/bin/klr.host.dll Information : 0 : [LoaderContainer]: Load name=Nancy.Owin
/home/vnext/.kre/packages/KRE-mono45-x86.1.0.0-alpha3/bin/klr.host.dll Information : 0 : [DefaultLoaderEngine]: LoadFile(/home/vnext/.kpm/packages/Nancy.Owin/0.23.2/lib/net40/Nancy.Owin.dll)
/home/vnext/.kre/packages/KRE-mono45-x86.1.0.0-alpha3/bin/klr.host.dll Information : 0 : [NuGetAssemblyLoader]: Loaded name=Nancy.Owin in 1ms
It will load a normal html view when I place it in the KRE bin directory but not in the project's View folder.
How can I force Nancy to look in the right folder, and how can I load the Razor viewengine?
This is the code that i've used: https://github.com/matthijsbreemans/nancy-owin-vnext
Nancy scans the AppDomain.CurrentDomain.BaseDirectory for assemblies by default. In vNext, the assemblies are stored in separate packages, and not in the bin directory, therefore it cannot find the Razor view engine. Until full support is available you can implement your own bootstrapper and override the ViewEngines list:
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
base.ConfigureApplicationContainer(container);
container.Register<IViewEngine, Nancy.ViewEngines.Razor.RazorViewEngine>();
container.Register<Nancy.ViewEngines.Razor.IRazorConfiguration, Nancy. ViewEngines.Razor.DefaultRazorConfiguration>();
}
protected override IEnumerable<Type> ViewEngines
{
get { return new[] { typeof(Nancy.ViewEngines.Razor.RazorViewEngine) }; }
}
The views are also stored in a different directory (especially when published). Create a new class that implements IRootPathProvider, and return the IApplicationEnvironment.ApplicationBasePath. I've done this (for now as a workaround) by storing the IApplicationEnvironment in a static variable (the IoC in Nancy itself can't find an instance when using it in the bootstrapper):
public class Startup
{
internal static IApplicationEnvironment Environment { get; private set; }
public Startup(IApplicationEnvironment env)
{
Environment = env;
}
public void ConfigureServices(IServiceCollection services) { }
public void Configure(IApplicationBuilder app)
{
app.UseOwin(a => a.UseNancy());
}
}
and implement Nancy's IRootPathProvider:
public class vNextRootPathProvider : IRootPathProvider
{
private string BasePath = Startup.Environment.ApplicationBasePath;
public string GetRootPath()
{
return BasePath;
}
}
KRE can't found the views directory, you can custom the Bootstrapper and override IRootPathProvider , setting the root directory to absolute path. Look at : https://github.com/NancyFx/Nancy/wiki/The-root-path