JSPX leads to copy-paste code? - jspx

As soon as JSPX must be a well-formed XML, there is no way of having header part including beginig of tag in separate included file, since must be closed.
Looks like you must always include into all of your main pages?
Or do I miss something?

Apache Tiles supposedly solves this problem, it allows you to template and re-use JSPX components.
Updated answer:
In your views.xml, you would have something like the following:
<definition extends="error" name="dataAccessFailure">
<put-attribute name="body" value="/WEB-INF/views/dataAccessFailure.jspx"/>
</definition>
<definition extends="default" name="index">
<put-attribute name="body" value="/WEB-INF/views/body/index.jspx"/>
<put-attribute name="side" value="/WEB-INF/views/side/index.jspx"/>
</definition>
Both error and default are layouts I've defined in the layouts directory, error is a single column layout and default is a two column layout.
Also in the layouts directory is the layouts.xml:
<tiles-definitions>
<definition name="default" template="/WEB-INF/layouts/default.jspx">
<put-attribute name="header" value="/WEB-INF/views/header.jspx" />
<put-attribute name="menu" value="/WEB-INF/views/navigation.jspx" />
<put-attribute name="footer" value="/WEB-INF/views/footer.jspx" />
</definition>
<definition name="error" template="/WEB-INF/layouts/error.jspx">
<put-attribute name="header" value="/WEB-INF/views/header.jspx" />
<put-attribute name="menu" value="/WEB-INF/views/navigation.jspx" />
<put-attribute name="footer" value="/WEB-INF/views/footer.jspx" />
</definition>
</tiles-definitions>
I haven't personally done apache tiles integration by hand, I just use Spring ROO to generate a complete stack for me and then add / remove stuff as I need.

Related

Spring Security Intercept-url pattern not working

My application can have below URLs:
/siteadmin/homepage/
/siteusers/customer/createCustomer
Below is my spring-security.xml:
<beans:beans>
<http auto-config="true">
<intercept-url pattern="/siteusers***" access="isAuthenticated()" />
<!-- <intercept-url pattern="siteusers/home/*" access="hasRole('USER') OR hasRole('ADMIN')" /> -->
<intercept-url pattern="/siteadmin***" access="hasRole('ROLE_ADMIN')" />`enter code here`
<form-login login-page="/siteusers/loginprocess/login" default-target-url="/siteusers/home/homepage"
login-processing-url="/siteusers/loginprocess/login"
authentication-failure-url="/siteusers/loginprocess/login?error" username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/siteusers/loginprocess/login?logout" logout-url="/siteusers/loginprocess/logout" />
<!-- enable csrf protection -->
<csrf />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="b" password="123456" authorities="ROLE_ADMIN" />
<user name="a" password="a" authorities="ROLE_USER" /><!-- This user can not access /admin url -->
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
If I logged in with user 'a' and hit URL http://localhost:8080/siteadmin/homepage/ it is allowing user 'a' to view the page although his role is not admin. But when I try to hit http://localhost:8080/siteadmin then Spring Security is working fine ie. its showing access denied page.
I want to restrict /admin/* URLs for users who doesn't have Admin role.
See AntPathMatcher:
The mapping matches URLs using the following rules:
? matches one character
* matches zero or more characters
** matches zero or more directories in a path
Some examples:
com/t?st.jsp - matches com/test.jsp but also com/tast.jsp or com/txst.jsp
com/*.jsp - matches all .jsp files in the com directory
com/**/test.jsp - matches all test.jsp files underneath the com path
org/springframework/**/*.jsp - matches all .jsp files underneath the org/springframework path
org/**/servlet/bla.jsp - matches org/springframework/servlet/bla.jsp but also org/springframework/testing/servlet/bla.jsp and org/servlet/bla.jsp
Your pattern /siteadmin***misses slashes. Use /siteadmin/**.

log4net doesn't create log file when deployed on IIS7

Good morning everybody,
I have a log4net issue that didn't exist when I was developing on my
local machine, but once I deployed the application to a server, log4net stopped working.
This is the server configuration :
-Windows XP SP3
-IIS 7
-framework .Net v4
This is the log4net configuration in the web.config of the website:
<configuration>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="30MB" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
</log4net>
</configuration>
I also have a class library and this is its App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="30MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
</log4net>
</configuration>
This is how I call the log function on every class:
private static readonly ILog log = LogManager.GetLogger(typeof(AppDomain));
...and this is how i call it :
log.Error("\n\t=>" + ex.GetBaseException().Message + "\n\r" + " # " + Environment.StackTrace);
It could be that you do not have permissions to write to the file 'log.txt'.
I don't know what the current directory would be but it's unlikely to be somewhere IIS can write to.
You need to create a folder somewhere and grant access for IIS to write to it, I understand you need to grant access to the IIS_IUSRS group and then specify the absolute path to that file. e.g.
<param name="File" value="D:\Logs\log.txt" />
..using the path to your preferred location.
When it comes to writing log files I tend not to try and write my log files anywhere in the program files directory or anything in any virtual directory just because of the previous battles I've had with security issues. Currently I'm using something like the following for all my log4net log files:
<file type="log4net.Util.PatternString" value="${ALLUSERSPROFILE}/<Product Name>/Logs/<Program Name>/<Program Name>.log" />
${ALLUSERSPROFILE} is the key above. This directory typically doesn't have the security restrictions as virtual directory and the program files directory. I've found that I haven't had any trouble since I've been using this path.
This envrionment variable takes you to the ProgramData directory in Windows Vista, 7, 8, Server 2008 etc. I think XP takes you to a different place but still a directory with relaxed permissions.
On a side note your log statement above:
log.Error("\n\t=>" + ex.GetBaseException().Message + "\n\r" + " # " + Environment.StackTrace);
Can be shortened to: log.Error(ex); Unless the formatting is a must. But if you write it like that and deploy your binaries with the pdbs the exceptions you log will contain the full stack trace and the line number the error occurred on.
Edit:
Log files will also fail to create if you have invalid log4net configuration. If you are sure that you have write access to the folder specified in your log4net configuration I would suggest enabling log4net debugging by first setting debug="true" in your log4net config section:
<log4net debug="true">
...
</log4net>
Setting the above debug flag will tell log4net to output all it's logging via windows trace listeners. To capture this trace listener output you will have to add a section like the following to your app.config:
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
Make sure the path specified in the above trace listener config in app.config exists and that you have write access to the folder!
I had the same problem myself and it turned out that I had forgot to set the "Build Action" for the configuration file. Therefore the log4net.config file was not deployed, and this is of course needed to make the application write the log file.
The log folder directory should be given the permission under which IIS is running. e.g. if IIS is run as network service then add Network service account the directory and give full permission to it.
Check with reference to following configuration in web.config. If everything good , check the write permission of inetpub sub-folder using the application pool owner. If not grant full permission.
Hope it will resolve your issue
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net debug="true">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n %newline--%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>

Spring Security Authentication is not working as expected in my configuration

I have configured spring authentication as below and its not working as expected
<sec:http auto-config="true">
<!-- Restrict URLs based on role -->
<sec:intercept-url pattern="pages/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/css/style.css" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="pages/**" access="ROLE_USER" />
<!-- Override default login and logout pages -->
<sec:form-login login-page="/login.jsp"
default-target-url="/pages/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<sec:logout logout-url="/logout" logout-success-url="/login.jsp" />
</sec:http>
On server start up i have been redirected to login.jsp ,if i use login form i am redirected to products.xhtml so far fine but if i directly access products.xhtml , it just allowing me to access the product.xhtml(Even after closing the broser or even on server restart) instead of redirecting to login.jsp . Could anyone just me what i am missing exactly?
Thanks & Regards
Vijay
Your patterns and URLs aren't consistent. You have "/login.jsp" for the login page and "pages/login.jsp" in the intercept-url pattern.
Try using:
<http pattern="/css/**" security="none">
<http>
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login.jsp"
default-target-url="/pages/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<logout logout-url="/logout" logout-success-url="/login.jsp" />
</http>
The debug log for a particular request will explain exactly why it is or isn't secured.
Make sure you do not have a Cookie or a valid session...

Can Log4net have multiple appenders write to the same file?

I'm using a RollingFileAppender to log some info to a file with a conversionPattern (in the web.config) that looks like this for the header of each log section:
<conversionPattern value="%date - %property{userId} - %property{method}%newline--------------------------------%newline%message%newline%newline"/>
I'd like to log details under this header as bullet points. I'm currently trying to use another RollingFileAppender that logs to the same file with a simple conversionPattern of just a dash, like this:
<conversionPattern value="- %message%newline"/>
But these messages aren't making it into the log file. I'm using Log.Info() for the header and Log.Debug() for the bullet points and filtering each appender on their respective log levels. Is what I'm trying to do possible? Or is there a better way to get header and detail information into a log file from log4net?
Yes you can have two log4net appenders that append (write) to the same log file.
You need to place the following line in each of your Appenders:
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
This will make log4net use a minimal locking model that allows multiple processes to write to the same file.
Here's an example XML that uses two appenders writing to the same log file:
<log4net debug="false">
<appender name="RollingLogFileAppender1" type="log4net.Appender.RollingFileAppender">
<!-- this configures a log for the application messages -->
<file value="TestLog.log" />
<appendToFile value="true" />
<!-- next line uses a minimal locking model that allows multiple processes to write to the same file -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<!-- make the most recent log the highest numbered log -->
<countDirection value="1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date{MM-dd-yyyy HH:mm:ss.ff} [%property{NDC}] %message%newline [Thread: %thread] %c{1} Method:%method(%file{1}, Line:%line) %newline" />
</layout>
<!-- The following two filters insure only log requests of
version '1' use this Appender -->
</appender>
<appender name="RollingLogFileAppender2" type="log4net.Appender.RollingFileAppender">
<file value="TestLog.log" />
<appendToFile value="true" />
<!-- next line uses a minimal locking model that allows multiple processes to write to the same file -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<!-- make the most recent log the highest numbered log -->
<countDirection value="1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date{MM-dd-yyyy HH:mm:ss.ff} [%property{NDC}] [Thread: %thread] %c{1} Method:%method(%file{1}, Line:%line) %newline%message" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender1" />
<appender-ref ref="RollingLogFileAppender2" />
</root>
This can be found in the Apache documentation here:
Apache Log4Net Docs
Just search on this page for 'same file'.
Hope this helps.
You could realize if there is any problem with log4net checking the output window on visual studio. The library log errors there, very useful to detect configuration mistakes.

PreCompile ASP.net mvc

I believe you can pre compile a asp.net mvc application but there are some issues with aspx files.
Is it correct to say the view folder needs to be copied to the deployed location?
If so does anyone know why?
Thanks
The short answer is that ASPX (and ASCX) files don't get compiled and must be copied with your application when you deploy to IIS.
You can precompile an ASP.NET MVC application, but the ASPX/ASCX files don't get included in the mix. In our experience, we weren't able to use aspnet_compiler.exe to bundle everything into a binary, so we use csc (via nant) to compile all of the stuff that can be compiled, and then copy the rest. This includes the View folder.
If it helps, the relevant portion of one of our nant scripts is as follows:
(Assuming all dependencies have already been copied to the site folder's (BuildDir in this case) bin folder)
<csc target="library" output="${BuildDir}/bin/${FinalDeployDllName}.dll" >
<references failonempty="true">
<include name="${BuildDir}/bin/SomeDependency.dll" />
</references>
<sources>
<include name="${BuildDir}/**/*.cs" />
</sources>
</csc>
<copy todir="${target}" overwrite="true">
<fileset basedir="${BuildDir}">
<include name="**/*.???x" />
<include name="**/*.js" />
<include name="**/*.jpg" />
<include name="**/*.jpeg" />
<include name="**/*.gif" />
<include name="**/*.png" />
<include name="**/*.html" />
<include name="**/*.css" />
<include name="**/*.swf" />
<include name="**/*.Master" />
<include name="**/Web.config" />
<include name="images/**/*" />
<include name="bin/**/*" />
<include name="Content/**/*" />
</fileset>
</copy>
<delete>
<fileset>
<include name="${target}/*.build" />
<include name="${target}/*.scc" />
<include name="${target}/*.sln" />
<include name="${target}/*.suo" />
<include name="${target}/build.*" />
<include name="${target}/*.resharper" />
<include name="${target}/*.resharper.user" />
<include name="${target}/bin/*.xml" />
<include name="${target}/bin/*.pdb" />
</fileset>
</delete>
This'll create a folder at {target} with all the required files for deployment, to be packaged from there as you see fit.
I've always used Web Deployment Projects to precompile web applications and prepare them for deployment. Scott Guthrie has blogged about it.

Resources