.NET 4.5 SessionAuthenticationModule - Issue with "validFrom" - .net-4.5

I'm using SWT in Windows Azure ACS and custom SwtHandler is used in Relying Party applicaiton to handle incoming SWT token. While it re-creates the SWT token at relying party, I get an error with creation of SessionSecurityToken related to value of validFrom attribute.
I've tried out following values for ValidFrom, but didn't fix the problem.
DateTime SwtBaseTime = new DateTime( 1970, 1, 1, 0, 0, 0, 0 );
DateTime.UtcNow
DateTime.MinValue
Specified argument was out of the range of valid values.
Parameter name: validFrom
[ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: validFrom]
System.IdentityModel.Tokens.SessionSecurityToken..ctor(ClaimsPrincipal claimsPrincipal, UniqueId contextId, String id, String context, Byte[] key, String endpointId, Nullable1 validFrom, Nullable1 validTo, UniqueId keyGeneration, Nullable1 keyEffectiveTime, Nullable1 keyExpirationTime, SctAuthorizationPolicy sctAuthorizationPolicy, Uri securityContextSecurityTokenWrapperSecureConversationVersion) +1009610
System.IdentityModel.Tokens.SessionSecurityToken..ctor(ClaimsPrincipal claimsPrincipal, UniqueId contextId, String context, String endpointId, Nullable1 validFrom, Nullable1 validTo, SymmetricSecurityKey key) +317
System.IdentityModel.Tokens.SessionSecurityTokenHandler.CreateSessionSecurityToken(ClaimsPrincipal principal, String context, String endpointId, DateTime validFrom, DateTime validTo) +306
System.IdentityModel.Services.SessionAuthenticationModule.CreateSessionSecurityToken(ClaimsPrincipal principal, String context, DateTime validFrom, DateTime validTo, Boolean isPersistent) +313
System.IdentityModel.Services.WSFederationAuthenticationModule.SignInWithResponseMessage(HttpRequestBase request) +1079
System.IdentityModel.Services.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args) +123924
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165

I ran into a similar problem recreating the session security token while trying to implement sliding expiration for the SessionAuthenticationModule.
protected void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
{
DateTime now = DateTime.UtcNow;
DateTime validFrom = e.SessionToken.ValidFrom;
DateTime validTo = e.SessionToken.ValidTo;
TimeSpan sessionLifetime = validTo.Subtract(e.SessionToken.ValidFrom);
bool sessionTimeHasExpired = now > validTo;
bool sessionTimeIsHalfExpired = now > validFrom.AddMinutes(sessionLifetime.TotalMinutes / 2);
// http://www.michael-mckenna.com/Blog/2013/2/the-problem-with-absolute-token-expiration-in-windows-identity-foundation-wif
if (!sessionTimeHasExpired && sessionTimeIsHalfExpired)
{
// If the session has not expired but the session lifetime is already half spent, reissue the cookie.
e.SessionToken = (sender as SessionAuthenticationModule).CreateSessionSecurityToken(e.SessionToken.ClaimsPrincipal, e.SessionToken.Context,
now, now.AddMinutes(sessionLifetime.TotalMinutes), e.SessionToken.IsPersistent);
e.ReissueCookie = true;
}
}
The CreateSessionSecurityToken method takes a value for validFrom and validTo. If these two values are equal, it throws an ArgumentOutOfRange exception.
I ran into the problem because originally I was using sessionLifetime.Minutes (which was 0) rather than sessionLifetime.TotalMinutes (which was 100).

Try using the same KeyEffectiveTime
e.SessionToken = sam.CreateSessionSecurityToken(
e.SessionToken.ClaimsPrincipal,
e.SessionToken.Context,
e.SessionToken.KeyEffectiveTime,
e.SessionToken.KeyExpirationTime.AddHours(8),
e.SessionToken.IsPersistent);

Related

What is the correct syntax to pass a null value for a timestamp column using Npgsql?

I have an AWS Redshift table with a timestamp type column.
create table if not exists testtimestampfields
(
testid varchar(50) not null,
creationdate timestamp null
);
Since the creationdate field permits null, I thought I could pass a null DateTime as the parameter value when inserting records.
[Fact]
public async Task Can_insert_null_timestamp_field()
{
// Custom class that calls GetClusterCredentials and returns a connection with the user and password...
await using var conn = await _redshiftConnectionManager.GetConnectionAsync();
await conn.OpenAsync();
await using var cmd = new NpgsqlCommand(
#"insert into testtimestampfields(testid, creationdate) values (#testid, #creationdate);", conn);
var testidParam = cmd.Parameters.Add("#testid", NpgsqlDbType.Varchar);
var creationDateParam = cmd.Parameters.Add("#creationdate", NpgsqlDbType.Timestamp);
testidParam.Value = Guid.NewGuid().ToString();
creationDateParam.Value = null;
await cmd.ExecuteNonQueryAsync();
}
But when I try this await cmd.ExecuteNonQueryAsync(); fails with:
System.InvalidCastException: Parameter #creationdate must be set
System.InvalidCastException
Parameter #creationdate must be set
at Npgsql.NpgsqlParameter.ValidateAndGetLength()
at Npgsql.NpgsqlParameterCollection.ValidateAndBind(ConnectorTypeMapper typeMapper)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken)
...
What is the correct syntax to pass a null value for a timestamp column using Npgsql?
Changing null to DBNull.Value works.
creationDateParam.Value = DBNull.Value;
Using a .NET DateTime? variable to set the parameter value conditionally:
creationDateParam.Value = dateTime.HasValue ? dateTime.Value : DBNull.Value;

How do we specify expiration date of JWT?

This the time for which we want the generated JWT to be valid for.
private String doGenerateToken(Map<String, Object> claims, String subject) {
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + jwtExpirationInMs)).signWith(SignatureAlgorithm.HS512, secret).compact();
}

mybatis passing in the datatype on dynamic update query

I am trying to create a dynamic update statement using dynamic-sql method and sql-builder method but I only manage it get it work for string datatype. I'm not exactly sure how to "cast" to the correct datatype when constructing the update statement.
What I want to achieve is to generate the update statement using Map<String, Object> or the actual pojo Post
Post look like this
public class Post {
private Integer id;
private String title;
private String body;
private LocalDateTime createdAt;
private String createdBy;
private LocalDateTime updatedAt;
private String updatedBy;
}
Reason for Map<String, Object> is so that it's easier to iterate through the collection and construct the statement. Using the pojo would require me to use reflection which I try not to.
Before getting into how I did it
This is how when using a normal update statement with the pojo looks like
#PutMapping("/{id}")
public Post updateById(#PathVariable Integer id, #RequestBody Post post) {
return this.postService.updateById(id, post);
}
#Update("UPDATE POST SET title = #{p.title}, body = #{p.body}, createdAt = #{p.createdAt}, createdBy = #{p.createdBy}, updatedAt = #{p.updatedAt}, updatedBy = #{p.updatedBy} WHERE id = #{id}")
public boolean updateById(#Param("id") Integer id, #Param("p") Post post);
That would result in
2021-10-30 12:03:15.037 DEBUG 15988 --- [nio-8080-exec-2] c.b.s.s.post.PostMapper.updateById : ==> Preparing: UPDATE POST SET title = ?, body = ?, createdAt = ?, createdBy = ?, updatedAt = ?, updatedBy = ? WHERE id = ?
2021-10-30 12:03:15.064 DEBUG 15988 --- [nio-8080-exec-2] c.b.s.s.post.PostMapper.updateById : ==> Parameters: jsonpatch1(String), bo21(String), 2021-10-30T12:03:14.954483(LocalDateTime), stackoverflow(String), 2021-10-30T12:03:14.954483(LocalDateTime), stackoverflow(String), 65(Integer)
So with that, I tried to do this
// What this does is to strip off all the null values, and keep only those with value
// and convert into a map to pass and run in the dynamic sql later
#PatchMapping(path = "/{id}")
public Post patchById(#PathVariable Integer id, #RequestBody Post post) {
ObjectMapper om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_NULL);
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(new JavaTimeModule());
Map<String, Object> mp = om.convertValue(post, new TypeReference<Map<String, Object>>(){});
return this.postService.patchById(id, mp);
}
Where it goes to a mapper that looks something like this
#Update({
"<script>",
"UPDATE POST",
"<set>",
"<foreach item='item' index='index' collection='p.entrySet()'>",
"${index} = #{item},",
"</foreach>",
"</set>",
"WHERE id = #{id}",
"</script>"
})
public boolean update(#Param("id") Integer id, #Param("p") Map<String, Object> post);
This works if all the values are string. However, if there is a field of LocalDateTime createdAt, the createdAt field is deem as a string type
021-10-30 15:21:27.666 DEBUG 12324 --- [nio-8080-exec-2] c.b.s.s.post.PostUpdateMapper.update : ==> Preparing: UPDATE POST SET createdAt = ?, title = ?, body = ?
WHERE id = ?
2021-10-30 15:21:27.669 DEBUG 12324 --- [nio-8080-exec-2] c.b.s.s.post.PostUpdateMapper.update : ==> Parameters: 2021-09-10T11:31:07.5306869(String), jsonpatch1(String), bo221(String), 65(Integer)
I believe, that is because I switch it to Map<String, Object> and hence the type (LocalDateTime) is loss with the conversion. However, if I were to do it using the pojo Bean
I would have something like this
#PatchMapping(path = "/{id}")
public Post patchById(#PathVariable Integer id, #RequestBody Post post) {
return this.postService.patchById(id, post);
}
#UpdateProvider(type=SQLUpdate.class, method = "update")
public boolean update(Integer id, Post post);
// just a poc to see if it works
public String update(Integer id, Post post) throws IllegalArgumentException, IllegalAccessException {
Field[] f = post.getClass().getDeclaredFields();
return new SQL() {{
UPDATE("POST");
for(Field field: f) {
field.setAccessible(true);
if (field.get(post) != null) {
SET(field.getName() + " = '" + field.get(post) + "'");
}
}
WHERE("id = " + id);
}}.toString();
}
So either way, I'm not sure how to pass in the correct type so that it can intercept and run correctly
This would be the more ideal solution if I can achieve this
#Update({
"<script>",
"UPDATE POST",
"<set>",
// being able to check if the value is null and set the field and value dynamically
"<if test='#{p.value} != null>p.fieldname = #{p.value}",
"</set>",
"WHERE id = #{id}",
"</script>"
})
public boolean update(#Param("id") Integer id, #Param("p") Post post);
Let me know if more information is needed, or if there is a better way to achieve what I want to do
Thanks!
P.S: I know and I got it working with mybatis-dynamic-sql lib but interested to know if it cab work without using the lib

Asp.net core rc1, dbcontext connection is closed in IStringLocalizer GetString method

Asp.net core rc1, dbcontext connection is closed in IStringLocalizer GetString method. Happening only when VS2015 is on Debug mode and only once at start up.
I am using Autofac DI, but same issue (without autofac) using the buildin DI.
When I am running the App in debug mode and only at start up, producing the following error. When I refresh the browser all fine, no errors. If I run the App without debugging, no errors, everything runs normally.
Something's wrong with the debugging threat and the DI? Any ideas?
Error on browser:
A database operation failed while processing the request.
InvalidOperationException: ExecuteReader requires an open and
available Connection. The connection's current state is closed.
Output window:
Microsoft.Data.Entity.Storage.Internal.RelationalCommandBuilderFactory: Information: Executed DbCommand (55ms) [Parameters=[#___cultureName_0='?', #__name_1='?'], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [l].[CultureId], [l].[Name], [l].[Value]
FROM [UIResources] AS [l]
WHERE ([l].[CultureId] = #___cultureName_0) AND ([l].[Name] = #__name_1)
Microsoft.Data.Entity.Query.Internal.QueryCompiler: Error: An exception occurred in the database while iterating the results of a query.
System.NullReferenceException: Not Specified object reference to an instance object.
σε System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
σε System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
σε System.Data.SqlClient.SqlConnection.Open()
σε Microsoft.Data.Entity.Storage.RelationalConnection.Open()
σε Microsoft.Data.Entity.Query.Internal.QueryingEnumerable.Enumerator.MoveNext()
σε System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
σε System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
σε lambda_method(Closure , QueryContext )
σε Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass18_1`1.<CompileQuery>b__1(QueryContext qc)
Microsoft.Data.Entity.Query.Internal.QueryCompiler: Error: An exception occurred in the database while iterating the results of a query.
System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is closed.
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at Microsoft.Data.Entity.Storage.Internal.RelationalCommand.<>c__DisplayClass17_0.<ExecuteReader>b__0(DbCommand cmd, IRelationalConnection con)
at Microsoft.Data.Entity.Storage.Internal.RelationalCommand.Execute[T](IRelationalConnection connection, Func`3 action, String executeMethod, Boolean openConnection, Boolean closeConnection)
at Microsoft.Data.Entity.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, Boolean manageConnection)
at Microsoft.Data.Entity.Query.Internal.QueryingEnumerable.Enumerator.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at lambda_method(Closure , QueryContext )
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass18_1`1.<CompileQuery>b__1(QueryContext qc)
Exception thrown: 'System.NullReferenceException' in EntityFramework.Core.dll
Exception thrown: 'System.InvalidOperationException' in EntityFramework.Core.dll
This is my startup:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc().AddViewLocalization();
services.AddMvc().AddDataAnnotationsLocalization();
services.AddLocalization();
// Create the Autofac container builder.
var builder = new ContainerBuilder();
// Populate the services from the collection.
// This have to come First.
builder.Populate(services);
// Register dependencies.
builder.RegisterType<AuthMessageSender>().As<IEmailSender>().InstancePerLifetimeScope();
builder.RegisterType<AuthMessageSender>().As<ISmsSender>().InstancePerLifetimeScope();
builder.RegisterType<DataInitializer>().As<IDataInitializer>().InstancePerLifetimeScope();
builder.RegisterType<CultureHelper>().As<ICultureHelper>().InstancePerLifetimeScope();
builder.RegisterType<RouteRequestCultureProvider>().InstancePerLifetimeScope();
builder.RegisterType<CultureActionFilter>().InstancePerLifetimeScope();
builder.RegisterType<DbStringLocalizerFactory>().As<IStringLocalizerFactory>().InstancePerLifetimeScope();
// DbStringLocalizer registers with InstancePerDependency,
// because localization requires a new instance of IStringLocalizer created in the IStringLocalizerFactory.
builder.RegisterType<DbStringLocalizer>().As<IStringLocalizer>().InstancePerDependency();
// Build the container.
var container = builder.Build();
// Return the IServiceProvider resolved from the container.
return container.Resolve<IServiceProvider>();
}
This is Localization implementation:
public class DbStringLocalizerFactory : IStringLocalizerFactory
{
private IServiceProvider _serviceProvider;
public DbStringLocalizerFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IStringLocalizer Create(Type resourceSource)
{
return _serviceProvider.GetService<IStringLocalizer>();
}
public IStringLocalizer Create(string baseName, string location)
{
return _serviceProvider.GetService<IStringLocalizer>();
}
}
public class DbStringLocalizer : IStringLocalizer
{
private ApplicationDbContext _db;
private string _cultureName;
public DbStringLocalizer(ApplicationDbContext db)
: this(db, CultureInfo.CurrentCulture)
{
}
public DbStringLocalizer(ApplicationDbContext db, CultureInfo cultureInfo)
{
_db = db;
_cultureName = cultureInfo.Name;
}
public LocalizedString this[string name]
{
get
{
var value = GetString(name);
return new LocalizedString(name, value ?? name, resourceNotFound: value == null);
}
}
public LocalizedString this[string name, params object[] arguments]
{
get
{
var format = GetString(name);
var value = string.Format(format ?? name, arguments);
return new LocalizedString(name, value, resourceNotFound: format == null);
}
}
private string GetString(string name)
{
//try
//{
var query = _db.UIResources.Where(l => l.CultureId == _cultureName);
var value = query.FirstOrDefault(l => l.Name == name);
return value?.Value;
//}
//catch
//{
// return null;
//}
}
public IEnumerable<LocalizedString> GetAllStrings(bool includeAncestorCultures)
{
return _db.UIResources.Where(l => l.CultureId == _cultureName)
.Select(l => new LocalizedString(l.Name, l.Value, true));
}
public IStringLocalizer WithCulture(CultureInfo culture)
{
return new DbStringLocalizer(_db, culture);
}
}
The IDataInitializer registration as scoped service in
builder.RegisterType<DataInitializer>().As<IDataInitializer>().InstancePerLifetimeScope();
seems odd, as a data initializer is expected to be called only once, when the application starts to ensure the database is created and filled with data required to run the application or after an update.
I suspect you dispose the scoped db context somewhere inside your DataInitializer class, so it becomes unavailable during your request because your IoC container will always return the same instance for the duration of the request.

how to write the JPQL to get list of data by day, month or year

here i'm having trouble getting list of data by either day , month or year in eclipse. i'm using entity manager to pull info from mySQL database.
i'm creating a web form whereby i can put in the value of the days that i want to view.
this is my Approval table's approval date.
#Temporal( TemporalType.DATE)
private Date approvedate;
it is auto created in eclipse when i add approval info.
approvedate = new Date();
in entity manager i put this:
#SuppressWarnings("unchecked")
public List<Approval> date(Date fromDate, Date toDate){
try {
Query query = entityManager
.createQuery("SELECT e from Approval e WHERE e.approvedate >= :startdate AND e.approvedate < :enddate");
query.setParameter("startdate", from);
query.setParameter( "enddate", to);
List<Approval> list = query.getResultList();
return list;
} catch (Exception e) {
return null;
}
}
and in the bean i put :
import java.text.ParseException;
import java.text.SimpleDateFormat;
private String start;
private String end;
private List<Approval> approvedate;
public String reportfrom() throws ParseException{
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
Date startDate = df.parse(start);
Date endDate = df.parse(end);
approvedate= tsm.date(startDate, endDate);
return "success";
}
and in my web form i had a box for user to put in the value:
View report of Approval from #{bean.start} and #{bean.end}
which is the input value for fromDate and toDate value. --> 01/01/2011, 08/08/2011
but i just could not pull out the data from approval table in mySQL.